Where the Budget Goes: Storage and Resources

In apple/container, CPU, memory, and disk settings describe resources assigned to lightweight guest VMs, not guaranteed slices of the Mac’s physical capacity. This chapter explains how to diagnose pressure and how to choose between host sharing, guest-local persistence, and temporary memory-backed storage. The aim is to keep configured capacity, actual guest use, and host allocation separate enough that a reader can make an informed operational decision.

The VM boundary makes the distinction unavoidable. An application container has a guest to boot, a kernel and guest support path to maintain, network devices to attach, and a writable filesystem to store. A BuildKit builder consumes a similar set of resources while it builds images. The project exposes controls and measurements for these costs, but no flag turns a configured limit into a performance guarantee.

Configured limits are not physical shares

For an ordinary container, the documented defaults are four CPUs and 1 GiB of memory. The BuildKit builder has separate defaults—two CPUs and 2 GiB—because building an image is a different workload from serving one. The persisted runtime configuration also accounts for CPU overhead used by guest support. These values are starting points for a guest, not statements that the Mac has reserved exactly that amount of physical capacity for the application.

apple/container allows requests to be overcommitted. A user can assign more virtual CPUs or memory across several containers than the Mac physically has. This works because macOS schedules host processes and guest VM processes together, as it schedules other competing work. It does not create more compute. CPU-bound guests share time and slow as contention increases; when real memory demand exceeds physical RAM, macOS can swap less-used pages and performance becomes increasingly limited by disk I/O.

Overcommit is therefore a capacity choice with a visible consequence. It can make a development machine convenient when not every container is busy at once, but it can make a collection of active builds, databases, and test workloads compete in ways that one container’s configured limits do not reveal. Leaving headroom for macOS and other applications is part of operating the system, not an admission that the limits failed.

The first diagnostic tool is container stats. For running containers it reports CPU use, memory use against the configured limit, network traffic, block I/O, and process count. Those measurements answer different questions. A high CPU value points toward compute contention or a busy process. A memory value near its limit points toward guest pressure. Network and block-I/O counters can show that apparent application slowness is associated with data movement rather than CPU. Process count can reveal a workload that is creating more children than expected.

A snapshot is more useful than a general impression. Compare a quiet container with the same container during its slow period, and compare guest usage with the host’s overall memory pressure. A configured 1 GiB limit does not say that the application will always consume 1 GiB, nor does a small current usage value say that the VM has no cost. The guest still has boot, agent, filesystem, and network overhead that belongs to the runtime rather than to the application’s measured working set.

Memory reclamation adds a second-order effect. The project documents that macOS Virtualization provides only partial memory ballooning support. Pages freed by processes inside a container’s VM are not currently fully relinquished to the host.