Try Hanzo

Benchmarks / Live agent footprint

measured

An agent as a goroutine

A dormant agent is a row; a running one still has to hold its place. 601 bytes of heap per live agent, 125 ns to spawn one, 107 ms to wake a million — and the three language runtimes that can sit inside one.

harness
hanzoai/cloud · bench/goroutine
our paper
What a Dormant Agent Costs
cd goroutine && go build -o /tmp/g . && /tmp/g

prints the table on this page — transcribed from bench/README.md, the pass of 2026-09-07

What is measured

A dormant agent is a row on disk. An agent that is running still has to hold its place, and the question is what that place costs. Here it is a goroutine: the heap it occupies, the time to start one, and the time to wake a million of them at once. The comparison column is what a platform built on V8 isolates publishes for the same two quantities.

Results

M-series laptop · the pass of 2026-09-07 · memory was identical on all five runs; timings are medians

measurementHanzo, measuredthe published figure
heap per live agent601 bytes1.2 MB per isolate, isolated-vm
one million live agents573.0 MB
spawn one125 ns2.79 ms, isolated-vm
wake one million107 ms — 107 ns each

601 bytes against a 128 MB container floor is about 223,000×, and against a V8 isolate about 1,745x and that second one is a goroutine against a JavaScript VM, so read it as what each primitive costs rather than as one beating the other. The isolate column is measured here rather than cited: a fresh isolated-vm isolate is 1.00 MiB and 0.35 ms on this laptop, close to the 1.2 MB attributed to it, because a megabyte is what any isolate costs including one of ours. The number that matters more for an interactive system is the 125 ns: an agent that costs nothing to start does not need to be kept warm, and a pool is a thing you maintain because starting was expensive.

What can run inside one

the same pass · instantiate is per context; call is a warm invocation

runtimelanguageinstantiatecall
wazeroWASM — any language that targets it7.8 µs20 ns
gojaJavaScript2.4 µs per VM740 ns warm eval
gpythonPython25.0 µs per context

WASM is not one language: CPython, QuickJS for TypeScript, Rust and Go all target it. A V8 isolate is JavaScript, and only JavaScript.

How to get this wrong

Benchmark a built binary. Under go run the compile is counted and spawn reads 253 ns instead of 125 ns, an error from the command you used to start the measurement. The reproduce line on this page builds first for exactly that reason.

Throw the first round away. A freshly built binary is slower the first time it runs, and not slightly: three fresh builds read 202, 210 and 201 ns, and the same three read 123, 125 and 123 ns when run again. The goroutines did not get cheaper. The window is 41 ms rather than 25 ms for the same 200,000 spawns, so it is one fixed cost inside the measurement, paid once per binary for first-touch paging and the kernel's signature check on first exec. Divided by 200,000 and printed per goroutine, it is the cost of starting the program wearing the name of the thing being measured. This page read 187 ns for months for exactly that reason; the harness now runs the round twice and reports the second.

A goroutine is not a sandbox. These agents share an address space. Nothing here is a security boundary, and an agent that must run untrusted code needs one — which costs 309 ms for a microVM boot, six orders of magnitude more than the spawn above. The two numbers answer different questions and a platform needs both.

One machine, one day. A single pass on one laptop, reproducible by one command. It establishes a floor; it is not a service level under load.

harness and the committed table: hanzoai/cloud · bench/goroutine · the paper: What a Dormant Agent Costs