Capacity,
measured
Every run gets its own gVisor sandbox, network namespace, and private subnet — and the whole apparatus idles at 24 MB and a quarter of a second per run. What binds a host depends on what your agents do: a triage fleet reaches the architectural ceiling of 256 before it strains anything, a build-heavy fleet is CPU-bound — and past saturation it degrades gracefully instead of failing. All of it measured on the production launch path, under live workloads.
Workload is the variable.
A sandbox's cost is a function of what the agent inside it is doing. At idle it is the isolation machinery alone. A triage agent — reading, searching, editing, running commands — adds a rounding error. A CI-shaped agent cycling dependency builds and browser-scale test suites is a different animal: modest on average, spiky at peak. Both were measured live, per-run, at the cgroup.
| Workload | Memory average | Memory burst peak | CPU average | CPU burst peak |
|---|---|---|---|---|
| Idle floor | 24 MB | — | 0.026 cores | — |
| Triage agent (20 tool calls/min) | 34 MB | — | 0.038 cores | 0.061 cores at 3× cadence |
| CI build + test cycle | 101 MB | 354 MB | 0.48 cores | 2.1 cores |
The triage workload drives the resident tool host with live bash, file, and search calls. The CI workload cycles a compile-shaped burst (JS compute, process spawns) and a browser-sized memory hold at a 40% duty cycle — averages are what a fleet costs over time; peaks are what you leave headroom for. CPU scales with how busy the agent is: tripling tool-call cadence takes a triage run from 0.038 to 0.061 cores — still noise against a build.
Flat to 128 live.
The isolation primitives are constant-time: spawning a sandbox onto a host already running 128 of them costs what it cost on an empty machine — and every sandbox on the host was running a live agent workload while these were measured, not sitting idle for the camera.
| Live sandboxes | Sandbox spawn | One more full run |
|---|---|---|
| 4 | 171 ms | 477 ms |
| 8 | 181 ms | 434 ms |
| 16 | 271 ms | 453 ms |
| 24 | 272 ms | 427 ms |
| 32 | 271 ms | 413 ms |
| 48 | 249 ms | 446 ms |
| 64 | 266 ms | 490 ms |
| 96 | 208 ms | 430 ms |
| 128 | 226 ms | 401 ms |
“One more full run” is the whole lifecycle — allocate a subnet, create the namespace, install firewall rules, boot the sandbox, get a live answer from the agent tool host inside, tear everything down — started while every other sandbox stays busy. Reclaiming a sandbox takes ~47 ms. The ceiling is architectural, not a performance cliff.
Size it to your fleet.
Pick the machine and the work; the measured coefficients do the rest. Capacity is the smallest of three limits — memory, CPU, and the per-host ceiling — and which one binds flips with the workload: triage fleets hit the ceiling, build fleets hit CPU.
Coefficients are the measured ones: triage sized at a busy 0.061 cores and 34 MB per run, CI at 0.48 cores and 101 MB cycle-averaged. ~2 GB stays reserved for the platform at rest.
spawn stays ~250 ms at every point on this curve
These are three different kinds of line. Memory and the ceiling are admission limits — past them, runs don't start. CPU is pacing: the solid zone runs every build at full speed, the faded zone fair-shares — builds stretch, nothing fails (measured below) — and past 2× is simply unmeasured, not unsafe.
Overload is a slowdown, not an outage.
Some hour, every agent decides to build at once and demand outruns the machine. That is a scheduling condition, not a failure mode: bursts fair-share, cycles stretch, everything completes. Verified the hard way — 32 sandboxes phase-locked to fire their builds in the same instant, each demanding ~2.1 cores of a machine with nowhere near that many.
| Simultaneous builds | Cores per build | Demand vs machine | Host CPU peak |
|---|---|---|---|
| 8 | 2.07 | 17 of 32 cores | 52% |
| 16 | 1.72 | 34 of 32 cores | 87% |
| 32 | 1.03 | 67 of 32 cores | 97% |
Under total oversubscription the kernel fair-shares: each burst compresses toward one core, cycles stretch, and work finishes late instead of failing. Nothing crashes, nothing is evicted, and isolation latency doesn't move. That's the property that makes sizing to averages safe — the penalty for a hot hour is throughput, never correctness.
Memory failure is contained the same way, at the smallest scope that can absorb it. A runaway command is stopped at its own memory budget and the agent is told why — it retries with a lighter approach while the session keeps its headroom. A run that outgrows its hard ceiling fails inside its own sandbox — resident memory pins at the limit, the allocation errors, and no neighbor ever notices. A leak costs a command, at worst a run — never the host.
256 by construction.
The 256-run limit isn't a tunable someone forgot to raise — it falls out of the isolation design. Every run owns a private /24 subnet carved from one reserved /16, so exactly 256 can exist on a host at once. The same structure that makes cross-run snooping impossible at the link layer sets the ceiling.
Runs never share a network segment, so there is no bridge to police and no policy to misconfigure — and no 257th slot to hand out. Need more than 256 concurrent agents? Add a host; capacity scales horizontally.
Inside the sandbox →Figures are medians measured on a commodity 32-core / 64 GB x86 host with a warm sandbox image cache, through the production launch path — capability broker, per-run subnet and namespace, gVisor sandbox, resident agent tool host. Per-run costs are read from each sandbox's own control group, so sandboxing overhead is inside every number. The triage workload issues live tool calls; the CI workload cycles compile-shaped bursts and browser-sized memory holds at a 40% duty cycle. Memory containment is verified with a blast-radius scenario: victim runs driven past their own ceiling pin at the limit and fail alone while neighbor runs take zero errors. Per-run figures exclude the host-side credential proxy (~24 MB per run) and orchestration, which the platform reserve covers. Real runs vary with task, model, and repository; treat the calculator as planning guidance and validate against your own workloads before committing hardware.