Cua

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.

Measured Build app 0.15.0, cua 0.9.0, cua-spacesd 0.8.0n = 64Result (JSON)

Results

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

8 forks
0.79 s
32 forks
3.09 s
64 forks
7.34 s
Values shown in the chart
MeasureValue
8 forks0.79 s
32 forks3.09 s
64 forks7.34 s
Samples64

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.

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.

Environment and build

MachineMac Studio, Mac14,13 (Mac Studio)
ChipApple M2 Max, 12 cores
Memory96 GB
OSmacOS 26.6.2 (25G83)
Wherelocal
Kindvm (QEMU 10.2.2 on HVF, Homebrew)
Imageghcr.io/trycua/linux:24.04-slim-disk (arm64, sha256:829c1dcf57d5356425483eebf5fb6fef20f943a7690a69308dcba24925fbb78b)
Shapeworld and every fork 2 vCPU / 2048 MiB
SettingsCUA_VM_VCPU_OVERCOMMIT=12 (NON-DEFAULT; default 8). FORKABLE=1, WARM=0, DIRTY_MB=300
Other vms1
Networkn/a (local)
BuildCua 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
App0.15.0
cua0.9.0
cua_spacesd0.8.0

Reproduce

# 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

Cua commands use the published Cua Spaces 0.15.0 release and the public trycua/cua repository at the tag cua-spaces-v0.15.0. Downloads: result (JSON), this page as Markdown. This run recorded summary percentiles, not one row per sample, so there is no CSV.

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.

Checked 2026-10-25. Sources: the samples and result files above, measured by Cua. All benchmarks.

Open in your browser to continue

Sign-in often fails inside this app's built-in browser. Open this page in Safari or Chrome to continue.