rust-nano-vm

A single-binary Rust microVM for AI-agent code execution.

Rust KVM Apache-2.0 / MIT Linux

~12 mscold start, p50 (snapshot → fork)
~0.5 MiBprivate memory per fork (Pss, N=50)
>90%shared via MAP_PRIVATE CoW
~30 000concurrent forks per 16 GiB host*

* For minimal-footprint guests. Measured on an i5 laptop, 8 GiB RAM, vanilla Linux + KVM. Reproduce with cargo run -p bench --features kvm --release -- --count 100 --alive 50.

The problem

Every AI coding agent — Claude Code, Cursor, Devin, OpenHands, aider, SWE-bench-style evals — needs to run generated code somewhere safe and cheaply. Today the options force a bad trade-off:

The shape of the solution

A single-binary Rust VMM + guest agent + REST control plane, snapshot-first, with snapshot → fork as a first-class primitive. An eval pipeline can spawn 1000 variants of a base image at ~12 ms each. The kernel keeps the shared 6–7 MiB golden image actually shared across all of them via MAP_PRIVATE copy-on-write.

Comparison

AxisE2BFirecrackerrust-nano-vm
Cold start (p50)150–400 ms~125 ms~12 ms
Snapshot → forkservice-sidenot nativefirst-class
Per-fork memoryopaque~5 MiB+ RSS~0.5 MiB Pss
DistributionSaaS onlyVMM + jailer + your codeone binary
LicenseproprietaryApache-2.0Apache-2.0 / MIT
Control planeincluded (proprietary)bring your ownincluded (axum)

What's special

  1. Cold start is a mmap away. Fork doesn't re-boot a kernel — it maps the snapshot's RAM file MAP_PRIVATE and lets the kernel serve the read-only golden pages to every child. Read the write-up →
  2. Faithful KVM snapshot/restore in <1000 lines. Full vCPU + LAPIC + FPU + MSR + IRQCHIP + PIT capture, JSON-serialized via kvm-bindings's serde feature. Read the write-up →
  3. Honest accounting. The bench reports Pss (proportional set size, from /proc/self/smaps_rollup), not RSS. RSS double-counts shared pages and overstates fork cost by 5–10×.
  4. A production-shaped control plane. Bearer-token auth, per-token token-bucket quota on the expensive /fork route, per-caller usage metering, Prometheus /metrics endpoint. ~330 lines of axum, no magic.

30-second demo

git clone https://github.com/ip888/Rust-nano-vm.git
cd Rust-nano-vm
cargo build --release -p control-plane

NANOVM_API_TOKENS=dev-token \
  ./target/release/nanovm-control-plane &
until curl -sf localhost:8080/healthz >/dev/null; do sleep 0.1; done

TOKEN="Authorization: Bearer dev-token"
VM=$(curl -s -X POST localhost:8080/v1/vms      -H "$TOKEN" -H 'content-type: application/json' -d '{}' | jq -r .id)
curl -s -X POST localhost:8080/v1/vms/$VM/start  -H "$TOKEN" >/dev/null
SNAP=$(curl -s -X POST localhost:8080/v1/vms/$VM/snapshot -H "$TOKEN" | jq -r .id)

# Fork 5 children, ~milliseconds each:
for i in 1 2 3 4 5; do
  curl -s -X POST localhost:8080/v1/snapshots/$SNAP/fork -H "$TOKEN" \
    | jq -c '{vm: .vm.id, fork_ms, fork_count}'
done

curl -s localhost:8080/v1/usage -H "$TOKEN" | jq
curl -s localhost:8080/metrics  | head -20

Use cases this is built for