# How to Set CPU and Memory Limits for Containers and BuildKit Builder in Apple Container

> Learn to set CPU and memory limits for containers and BuildKit builder using flags or configuration files. Optimize resource allocation for Apple Container.

- Repository: [Apple/container](https://github.com/apple/container)
- Tags: how-to-guide
- Published: 2026-06-20

---

**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.swift`](https://github.com/apple/container/blob/main/Sources/ContainerPersistence/ContainerSystemConfig.swift) within the `ContainerConfig` struct, defaulting to **4 CPUs** and **1 GiB memory**.
- **BuildKit Builder defaults**: Also in [`ContainerSystemConfig.swift`](https://github.com/apple/container/blob/main/ContainerSystemConfig.swift) but within the `BuildConfig` struct, defaulting to **2 CPUs** and **2 GiB memory**.
- **Machine-wide fallbacks**: Computed from host hardware in [`Sources/ContainerPersistence/MachineConfig.swift`](https://github.com/apple/container/blob/main/Sources/ContainerPersistence/MachineConfig.swift) when 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:

1. **CLI Parsing**: Commands like `ContainerRun` and `BuilderStart` define `--cpus` and `--memory` options using `@Option(name: .shortAndLong)` annotations.
2. **Resource Conversion**: The `Parser.resources(cpus:memory:defaultCPUs:defaultMemory:)` method in [`Sources/ContainerAPIService/Client/Parser.swift`](https://github.com/apple/container/blob/main/Sources/ContainerAPIService/Client/Parser.swift) converts strings (like `"32g"`) into a typed `ResourceSpec`.
3. **VM Configuration**: The resulting `ResourceSpec` is assigned to `ContainerConfiguration.resources` before the `ContainerClient` creates the VM. For builders, `BuilderStart.start` in [`Sources/ContainerCommands/Builder/BuilderStart.swift`](https://github.com/apple/container/blob/main/Sources/ContainerCommands/Builder/BuilderStart.swift) handles 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`:

```bash

# 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:

```bash

# Start or restart the builder with enhanced resources

container builder start --cpus 8 --memory 32g

```

According to the implementation in [`BuilderStart.swift`](https://github.com/apple/container/blob/main/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`:

```toml
[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 `--cpus` and `--memory` with `container run` or `container builder start` to 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`](https://github.com/apple/container/blob/main/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.toml` or use `container system property set` to 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`](https://github.com/apple/container/blob/main/Sources/ContainerPersistence/ContainerSystemConfig.swift), though they may be overridden by machine-wide calculations in [`MachineConfig.swift`](https://github.com/apple/container/blob/main/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`](https://github.com/apple/container/blob/main/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`](https://github.com/apple/container/blob/main/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.