How to Configure Resource Limits (CPU and Memory) for Containers in Apple Container
In Apple Container, you configure CPU and memory limits through a three-layer hierarchy: command-line flags (--cpus and --memory) override per-machine settings, which in turn override system-wide defaults defined in config.toml.
The Apple Container tool manages container execution through a layered configuration system defined in the Swift source codebase. To effectively configure resource limits (CPU and memory) for containers, you must understand how the system resolves configuration values across different scopes, from global defaults to runtime overrides.
Understanding the Resource Configuration Hierarchy
Resource allocation follows a strict precedence order implemented in Sources/ContainerPersistence/ContainerSystemConfig.swift. When you execute a container command, the system builds a final ContainerConfig object by applying configurations from lowest to highest priority:
- System-wide defaults from
[container]table inconfig.toml - Per-machine defaults from
[machine]sections orcontainer machine setcommands - CLI overrides from
--cpusand--memoryflags passed tocontainer run,container create, or related commands
System-Wide Defaults
The baseline resource limits reside in your config.toml configuration file. According to Sources/ContainerPersistence/ContainerSystemConfig.swift, the system defines defaultCPUs = 4 and defaultMemory = "1g", meaning every container receives 4 vCPUs and 1 GiB of RAM unless specified otherwise.
# ~/.config/container/config.toml
[container]
cpus = 4 # Default CPU count
memory = "1g" # Default memory allocation
These values are hard-coded in the Swift implementation and only change when you modify the configuration file or override them through higher-precedence methods.
Command-Line Overrides
The container run and container create commands expose --cpus and --memory flags that replace defaults for specific container instances. These flags accept integer values for CPU counts and human-readable strings for memory (e.g., 16g, 512m).
# Override CPU only
container run -d --cpus 8 my-image
# Override both CPU and memory
container run -d --cpus 8 --memory 32g my-image
# Create with specific resources without running
container create --cpus 2 --memory 4g my-image
The container builder start and container machine create commands also support these flags with their own default contexts, documented in docs/how-to.md and docs/command-reference.md.
Per-Machine Configuration
For named container machines, you can establish persistent defaults using the [machine] section in config.toml or the container machine set command. These settings apply whenever a specific machine is created unless CLI flags override them.
# Set defaults for a machine named "dev"
container machine set -n dev cpus=4 memory=8G
After execution, future container machine create -n dev commands inherit these resource limits until modified or overridden.
Configuration File Syntax and Memory Parsing
The container tool uses TOML format for configuration and supports human-readable memory strings. The parsing logic resides in Sources/ContainerPersistence/Measurement+Parse.swift, which interprets suffixes like g (gibibytes), m (mebibytes), and k (kibibytes).
[container]
cpus = 2
memory = "16g" # Valid: 16 GiB
memory = "512m" # Also valid: 512 MiB
Memory format rules:
- Use integers followed by unit suffixes
- Supported suffixes include
g,m, andk(case-insensitive) - Values are parsed into
Measurementobjects for internal storage
Practical Configuration Examples
Setting Persistent Defaults
Modify your system-wide defaults to reduce resource allocation for development environments:
# ~/.config/container/config.toml
[container]
cpus = 2
memory = "2g"
Builder VM Resource Allocation
The builder VM typically requires different resources than runtime containers. Configure it separately:
# Start builder with 6 CPUs and 8 GiB RAM
container builder start --cpus 6 --memory 8g
Builder defaults are defined separately in BuildConfig structures within the source code, often defaulting to 2 CPUs and 2 GiB RAM if not specified.
Container Machine Overrides
For project-specific machines with higher resource requirements:
# Create a high-performance machine
container machine set -n production cpus=16 memory=64G
container machine create -n production
Key Source Files and Implementation Details
| File | Purpose |
|---|---|
Sources/ContainerPersistence/ContainerSystemConfig.swift |
Defines ContainerSystemConfig struct with defaultCPUs and defaultMemory properties, plus ContainerConfig object construction |
Sources/ContainerPersistence/Measurement+Parse.swift |
Parses human-readable memory strings (e.g., "32g") into Swift Measurement objects |
docs/container-system-config.md |
Documents the [container] table schema and available configuration keys |
docs/command-reference.md |
Complete reference for --cpus and --memory flag syntax across all commands |
docs/how-to.md |
Practical examples for overriding defaults via CLI |
docs/container-machine.md |
Machine-specific configuration and container machine set documentation |
Summary
- Three-layer precedence determines final resource allocation: CLI flags (
--cpus,--memory) override per-machine settings, which override system-wide[container]defaults inconfig.toml - Default values are 4 vCPUs and 1 GiB RAM, defined in
ContainerSystemConfig.swift - Memory format supports human-readable strings (e.g., "16g", "512m") parsed by
Measurement+Parse.swift - Scope-specific overrides allow different defaults for builder VMs, container machines, and individual container instances
Frequently Asked Questions
What are the default CPU and memory limits for new containers?
By default, every container receives 4 vCPUs and 1 GiB of RAM. These values are hard-coded in Sources/ContainerPersistence/ContainerSystemConfig.swift as defaultCPUs = 4 and defaultMemory = "1g", and apply when you run container run without specifying resource limits.
Can I use human-readable memory values like "16g" or "512m"?
Yes. The container command accepts memory values with unit suffixes including g (gibibytes), m (mebibytes), and k (kibibytes). The parsing logic in Sources/ContainerPersistence/Measurement+Parse.swift converts these strings into internal measurements. For example, --memory 32g allocates 32 GiB of RAM.
How do I change resources for the builder VM specifically?
Use the container builder start command with --cpus and --memory flags: container builder start --cpus 6 --memory 8g. Builder VMs have separate defaults (typically 2 CPUs and 2 GiB) defined in the build configuration structs, distinct from runtime container defaults.
Where is the config.toml file located and what section configures defaults?
The configuration file is typically located at ~/.config/container/config.toml. Resource defaults reside under the [container] table using the keys cpus and memory. For machine-specific defaults, use the [machine] section or the container machine set command.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →