# How fast can one Mac fork 64 sandboxes from a running checkpoint?

With CUA_VM_VCPU_OVERCOMMIT raised from the default 8 to 12, one Mac forked 64 QEMU VMs (2 vCPU, 2 GiB each) from a running checkpoint in 7.34 s, first start to last fork ready, on a Mac Studio (Apple M2 Max, 96 GB), measured 2026-10-25. At the default setting the wave stops at fork 48.

- Page: https://cua.ai/benchmarks/fork-64-sandboxes-one-mac
- Measured: 2026-10-25
- Result: https://cua.ai/benchmarks/fork-64-sandboxes-one-mac.json (no per-sample CSV for this run)
- build Cua Spaces 0.15.0 DMG (https://github.com/trycua/cua/releases/download/cua-spaces-v0.15.0/cua-spaces-0.15.0-darwin-universal.dmg, sha256 8725a09ba4132aa8a1667fa48c86416c91d5dec0d3c7dc93f88f5f3e29e0aba0): bundled cua 0.9.0, Helpers/cua-spacesd 0.8.0, cua-vz; n = 64

## Results

Wall time per wave, every fork of a wave started at once (CUA_VM_VCPU_OVERCOMMIT=12). Lower is better.

| Measure | Value |
| --- | --- |
| 8 forks | 0.79 s |
| 32 forks | 3.09 s |
| 64 forks | 7.34 s |

## Method

Non-default setting: CUA_VM_VCPU_OVERCOMMIT=12, the documented host CPU overcommit (default 8; see the Cua SDK local runtimes guide). At the default, 64 forks of 2 vCPU need 128 vCPUs and the release refuses the 48th fork (see caveats).

Driver on the host: `bench/fork-fanout/run.sh` from tag cua-spaces-v0.15.0, which builds and runs the opt-in test `cua-daemon/tests/qemu_fork_fanout.rs` (release). It drives the release's QEMU runtime library directly (no daemon). A bake VM (2 vCPU / 2 GiB, published slim disk, forkable: RAM in a shareable file) dirties 300 MB of RAM, is checkpointed and pinned, then forked in waves of 8, 32 and 64 (every fork of a wave started at once). Per fork: fork + start until its cua-spacesd answers with its own token. The test checks every fork holds the world's RAM/disk state, its writes reach no other fork, and it shares the world's unwritten pages. Headline = wall time of the 64-wave (first start to last fork ready); private_mb_per_fork = host memory the wave added / forks.

## Environment

- Machine: Mac Studio, Mac14,13 (Mac Studio)
- Chip: Apple M2 Max, 12 cores
- Memory: 96 GB
- OS: macOS 26.6.2 (25G83)
- Where: local
- Kind: vm (QEMU 10.2.2 on HVF, Homebrew)
- Image: ghcr.io/trycua/linux:24.04-slim-disk (arm64, sha256:829c1dcf57d5356425483eebf5fb6fef20f943a7690a69308dcba24925fbb78b)
- Shape: world and every fork 2 vCPU / 2048 MiB
- Settings: CUA_VM_VCPU_OVERCOMMIT=12 (NON-DEFAULT; default 8). FORKABLE=1, WARM=0, DIRTY_MB=300
- Other vms: 1
- Network: n/a (local)
- Build: Cua Spaces 0.15.0 DMG (https://github.com/trycua/cua/releases/download/cua-spaces-v0.15.0/cua-spaces-0.15.0-darwin-universal.dmg, sha256 8725a09ba4132aa8a1667fa48c86416c91d5dec0d3c7dc93f88f5f3e29e0aba0): bundled cua 0.9.0, Helpers/cua-spacesd 0.8.0, cua-vz
- App: 0.15.0
- cua: 0.9.0
- cua_spacesd: 0.8.0

## Caveats

- Non-default setting: CUA_VM_VCPU_OVERCOMMIT=12. At the default (8), this 12-core Mac allows 96 vCPUs of VMs, so the 64-wave stops at fork 48. Same-day default run: 8 forks in 0.75 s, 32 forks in 3.68 s.
- One wave per size (n = forks in the wave), not repeated.
- Uses the QEMU runtime through a test binary built from the tag, not the daemon or CLI path.

## Reproduce

```sh
# On an Apple silicon Mac with Homebrew QEMU, crane and Rust:
git clone --depth 1 --branch cua-spaces-v0.15.0 https://github.com/trycua/cua && cd cua/libs/cua/bench/fork-fanout
mkdir -p /tmp/disk && crane export --platform linux/arm64 ghcr.io/trycua/linux:24.04-slim-disk - | tar -x -C /tmp/disk disk/disk.img
CUA_VM_VCPU_OVERCOMMIT=12 DISK=/tmp/disk/disk/disk.img WAVES=8,32,64 MEMORY_MB=2048 DIRTY_MB=300 FORKABLE=1 WARM=0 bash run.sh out.json
python3 check.py out.json baseline.json --host macos-hvf
```

## Questions

### Why the non-default setting?

64 forks of 2 vCPU need 128 vCPUs. At the default overcommit of 8 per core, this 12-core Mac allows 96, so the release refuses the 48th fork. CUA_VM_VCPU_OVERCOMMIT is a documented setting.

### How much memory does each fork add?

About 249.8 MB of private memory per fork in the 64-wave. Pages a fork hasn't written stay shared with the checkpoint.

### Can I run this myself?

Yes. The commands under Reproduce use the published Cua Spaces 0.15.0 release and the public trycua/cua repository at the tag cua-spaces-v0.15.0. A `cua bench run` command that wraps them is coming; it isn't in a release yet.
