How to Set CPU and Memory Limits for Containers and BuildKit Builder in Apple Container
Use the --cpus and --memory flags with container run for individual workloads or container builder start for the BuildKit builder, or define persistent defaults in ~/.config/container/config.toml or via container system property set.
The Apple Container project isolates workloads inside lightweight virtual machines (VMs) with strict resource boundaries. Unlike traditional container runtimes that share the host kernel, Apple Container creates a dedicated VM for each workload, allowing precise control over CPU count and memory allocation through properties defined in ContainerSystemConfig and applied via the Swift-based CLI.
Resource Architecture Overview
Apple Container enforces resource limits at the virtualization layer. Each container and the BuildKit builder run inside separate VMs whose hardware specs are determined by resource properties stored in the system configuration.
Where Default Resources Are Defined
Default values originate from three locations according to the source code in apple/container:
- Container VM defaults: Defined in
Sources/ContainerPersistence/ContainerSystemConfig.swiftwithin theContainerConfigstruct, defaulting to 4 CPUs and 1 GiB memory. - BuildKit Builder defaults: Also in
ContainerSystemConfig.swiftbut within theBuildConfigstruct, defaulting to 2 CPUs and 2 GiB memory. - Machine-wide fallbacks: Computed from host hardware in
Sources/ContainerPersistence/MachineConfig.swiftwhen no explicit values exist in the configuration file.
Runtime Resource Application Flow
When you execute a command with resource flags, the system processes limits through these Swift components:
- CLI Parsing: Commands like
ContainerRunandBuilderStartdefine--cpusand--memoryoptions using@Option(name: .shortAndLong)annotations. - Resource Conversion: The
Parser.resources(cpus:memory:defaultCPUs:defaultMemory:)method inSources/ContainerAPIService/Client/Parser.swiftconverts strings (like"32g") into a typedResourceSpec. - VM Configuration: The resulting
ResourceSpecis assigned toContainerConfiguration.resourcesbefore theContainerClientcreates the VM. For builders,BuilderStart.startinSources/ContainerCommands/Builder/BuilderStart.swifthandles the container creation with the specified kernel and resources.
Setting Limits for Regular Containers
Override default resources when starting a workload by appending the resource flags to container run:
# Allocate 8 CPUs and 32 GiB to a specific container
container run --rm --cpus 8 --memory 32g my-image:latest
These flags map to the ContainerConfig properties. If omitted, the container inherits the defaults from ContainerSystemConfig.container (4 CPUs, 1 GiB).
Configuring BuildKit Builder Resources
The BuildKit builder runs as a persistent utility container that requires separate resource management. Increase its capacity using the same flags with the builder subcommand:
# Start or restart the builder with enhanced resources
container builder start --cpus 8 --memory 32g
According to the implementation in BuilderStart.swift, the command compares existing resource allocations against requested values (tracked via cpuChanged and memChanged booleans). If the limits differ, the CLI automatically stops and deletes the existing builder container before launching a new VM with the updated ResourceSpec.
Persisting Default Configuration
To avoid specifying flags for every command, modify ~/.config/container/config.toml or use container system property set:
[container]
cpus = 4
memory = "2g"
[build]
cpus = 2
memory = "4g"
After updating the configuration, subsequent container run and container builder start invocations inherit these defaults unless overridden by CLI flags. The system reads these values through ContainerSystemConfig when initializing the ResourceSpec with Parser.resources.
Summary
- Runtime overrides: Use
--cpusand--memorywithcontainer runorcontainer builder startto set per-command limits. - Default values: Containers default to 4 CPUs and 1 GiB; the BuildKit builder defaults to 2 CPUs and 2 GiB as defined in
ContainerSystemConfig.swift. - Automatic replacement: Changing builder resources triggers an automatic stop and recreation of the builder VM to apply new limits.
- Persistent configuration: Edit
~/.config/container/config.tomlor usecontainer system property setto set machine-wide defaults that persist across sessions.
Frequently Asked Questions
What are the default CPU and memory limits in Apple Container?
By default, regular containers receive 4 CPUs and 1 GiB of memory, while the BuildKit builder receives 2 CPUs and 2 GiB of memory. These values are hardcoded in the ContainerConfig and BuildConfig structs within Sources/ContainerPersistence/ContainerSystemConfig.swift, though they may be overridden by machine-wide calculations in MachineConfig.swift if the configuration file is empty.
Will changing builder resources delete my existing builder?
Yes. When you run container builder start with new --cpus or --memory values, the logic in Sources/ContainerCommands/Builder/BuilderStart.swift detects the divergence (via cpuChanged and memChanged checks). The CLI then stops and removes the existing builder container before creating a new one with the updated ResourceSpec to ensure the limits are properly enforced by the underlying VM.
How does the CLI interpret memory values like "32g" or "512m"?
The Parser.resources(cpus:memory:defaultCPUs:defaultMemory:) method in Sources/ContainerAPIService/Client/Parser.swift handles string parsing for memory sizes. It converts human-readable suffixes (such as "g" for gigabytes or "m" for megabytes) into the internal ResourceSpec representation used by the virtualization layer, supporting both integer CPU counts and suffixed memory values.
Can I set persistent defaults without editing the config file directly?
Yes. While you can manually edit ~/.config/container/config.toml, the analysis indicates you can also use container system property set to modify the system configuration stored in ContainerSystemConfig. This approach updates the same underlying properties that define default resources for containers and the BuildKit builder without requiring direct file manipulation.
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 →