AI Agent Sandbox Runtime: The Six Options and Who Uses Them

Sep 3, 2026 · 10 min · Ajay Kumar

Disclosure up front: I built one of the platforms in the tables below — PandaStack, an Apache-2.0 Firecracker sandbox cloud. I've tried to describe it the way I'd describe a competitor, and I name where it loses rather than burying it: Modal beats me outright on GPU, which I don't have at all; Northflank's BYOC into your own cloud account is a stronger deployment story than "here's the source"; and E2B publishes its infrastructure repo with the development history intact where mine is a squashed cut. PandaStack is not the top pick in any of the recommendations at the end of this post.

Every agent-sandbox vendor sells you an API. Underneath that API is a runtime — the thing that actually creates the boundary and holds the state — and the runtime decides most of what the vendor can and cannot offer you. Not their roadmap. Not how much they raised. If a platform can't fork a running instance, or can't run a compiled binary, or charges you for a gigabyte of RAM you aren't using, the reason is almost always three layers down in a choice made before the SDK existed.

There are six runtimes in serious use across this category. This post is about what each one is, what it costs, and which providers are built on it.

I'm Ajay Kumar, an infrastructure engineer with 14 years in this; PandaStack is about 400 Go files built solo over six months, with 300+ organizations on it. My bias is obvious: I picked KVM microVMs and paid for that choice, and the middle third of this post is mostly an accounting of what that choice cost me. Every claim about another vendor here comes from that vendor's own documentation, and where the only source is a vendor's self-description I say "states" or "claimed" rather than presenting it as verified.

The six runtimes

Plain containers / namespaces. One shared Linux kernel. The boundary is a set of kernel features — namespaces, cgroups, seccomp, capabilities — restricting how a process sees the kernel every other tenant is also using. Syscall compatibility is perfect, because it is the real kernel. Start is tens of milliseconds once the image is local; the honest number includes image pull. Memory overhead is just the process RSS.

V8 isolates. No process, no filesystem, no kernel boundary. A JavaScript heap and context inside a host process that is already running. Syscall compatibility is nil — there is no fork, no exec, no ELF loader. Start is sub-millisecond, which is real but measures a different unit of work than every other row here. Memory is megabytes of heap, and you can pack thousands into one process.

gVisor. A userspace kernel. The Sentry implements a large subset of Linux in Go and services guest syscalls itself, reaching the host through a deliberately narrow, seccomp-restricted set of calls. Compatibility is good but not complete — the failure mode is a long-tail syscall, a /proc file or an ioctl the Sentry doesn't implement, which you hear about from a user rather than a test. Start is slower than runc, much faster than a cold VM boot. Overhead is the container plus a Sentry process per sandbox: real, well below a guest kernel's floor, and unmeasured by me, so I won't put a number on it.

Kata Containers. An OCI-compatible runtime that puts each pod or container inside a lightweight VM, usually on Cloud Hypervisor or Firecracker. You keep container tooling and gain a hypervisor boundary underneath. Compatibility is real Linux. Boot is a VM boot per workload — hundreds of milliseconds, not tens. Memory carries the full guest-kernel-plus-guest-RAM cost.

Firecracker / KVM microVMs. A minimal VMM: no BIOS, no PCI, a handful of virtio devices, one guest kernel per tenant on KVM. Compatibility is whatever your kernel supports, and you choose the kernel — which cuts both ways. The Firecracker project publishes a VMM overhead figure of under 5 MiB per microVM, and that number is almost irrelevant next to the guest RAM allocation, which is the actual cost. Cold boot is seconds; snapshot restore is where the interesting numbers live.

libkrun. A library-based KVM virtualizer. Same guest-kernel-per-sandbox boundary as Firecracker, but instead of supervising a jailed VMM process you link a library and get a microVM as a child of your own application. It collapses the operational layer while keeping the hardware boundary. It's the least deployed of the six in hosted products, and the main project using it is explicitly beta.

The runtime table

Runtime Boundary Syscall compat Start Memory per instance Runs under
V8 isolates V8 sandbox inside a host process None (JS/WASM only) Sub-ms MBs of heap Cloudflare Workers (the calling layer of the Sandbox SDK)
Containers Namespaces + cgroups + seccomp, shared kernel Full Tens of ms + image pull Process RSS Daytona, Cloudflare Sandbox SDK, OpenSandbox (default)
gVisor Userspace kernel (Sentry), narrowed host surface High, long-tail gaps Fast; slower than runc Container + Sentry (unmeasured by me) Modal, Google Agent Sandbox (default), Northflank (selectable)
Kata Guest kernel in a VM per pod Full Hundreds of ms Guest kernel + guest RAM Northflank (selectable), Google Agent Sandbox (option), OpenSandbox (opt-in)
Firecracker Guest kernel on KVM, minimal VMM Full, kernel is yours Seconds cold; ~180ms from snapshot Guest RAM allocation E2B, Vercel Sandbox, Fly Machines, CodeSandbox/Together, Blaxel, PandaStack
libkrun Guest kernel on KVM, VMM as a linked library Full Vendor-claimed fast; unmeasured Guest kernel + guest RAM Microsandbox

Two rows deserve a caveat. Runloop describes a custom bare-metal hypervisor with a VM-and-container two-layer model, which doesn't map cleanly onto any row. AWS Bedrock AgentCore is described as per-session microVM isolation, but I have not seen an AWS-primary page stating the hypervisor, so treat that as unconfirmed.

Who runs what

Platform Runtime Self-host Checkpoint primitive
E2B Firecracker Yes — Apache-2.0 infra, Terraform (GCP stable, AWS beta) pause() saves filesystem and memory
Vercel Sandbox Firecracker No (SDK public) Persistent by default; state auto-saves on stop
Fly Machines Firecracker No Suspend/resume via Firecracker snapshots
CodeSandbox SDK / Together Firecracker No Memory snapshots, fork from live VM or snapshot
Blaxel microVM (vendor says Firecracker) No Hibernate to standby with filesystem + memory
PandaStack Firecracker Yes — Apache-2.0, GCP/AWS/on-prem Named snapshots, CoW fork trees, hibernate/wake
Modal gVisor No Filesystem snapshots as Images + memory snapshots
Google Agent Sandbox gVisor (Kata option) Yes — k8s SIG project; managed on GKE GKE Pod snapshots (pause/resume)
Northflank Kata or gVisor, per workload Yes — BYOC to AWS/GCP/Azure/Oracle/Civo/bare metal Persistent volumes; no VM checkpoint API found
Daytona Container (VM classes offered) No — went closed source June 2026 Stateful environment snapshots
Cloudflare Sandbox SDK Container, driven from a V8 isolate No (SDK open source) Disk snapshots; sleep/wake with optional auto-snapshot
AWS AgentCore Code Interpreter microVM (unconfirmed) No None — ephemeral, session-scoped
Microsandbox libkrun Yes — Apache-2.0, local-first Claimed; beta software, verify hands-on
OpenSandbox Pluggable: container / gVisor / Kata / Firecracker Yes — Apache-2.0, self-host only Volumes and PVCs; pause/resume unverified

Sources are each vendor's own docs, with two things worth flagging: Daytona is still listed as open source in 2026 comparison articles and it isn't — the production codebase went closed in June 2026, and the public repo is explicitly unmaintained. And CodeSandbox is mid-migration into Together AI, so the product name may not survive the year.

Now the part that matters: what the runtime column does to you.

Constraint 1: the runtime decides whether "arbitrary code" is real

An isolate-based platform cannot run pip install pandas. Not because the vendor hasn't shipped it — because there is no process model to install into and no ELF loader to run the result. This is why Cloudflare's Sandbox SDK is a container product orchestrated from Workers rather than a Workers feature: the isolate does the routing and the container does the shell. That's a well-made architecture, and it's also an admission that the isolate can't do this job.

So the first question isn't latency, it's: what does the model actually emit? A pure transform over JSON, and isolates are extraordinary while everything else on this page is waste. apt-get, a compiler, a headless browser, a language server — you need a real kernel, and half the runtimes are gone before you compare anything else.

gVisor is the interesting boundary case, and I think it's underrated. It runs real binaries, and the gaps are narrow enough that most workloads never notice. But "most" is doing work in that sentence: if your product promise is "run whatever the agent wrote," you have signed up to debug other people's package installs against a kernel reimplementation, forever. If you control the images, that risk mostly evaporates.

Constraint 2: the runtime sets a memory floor, and the floor sets the price

This is where my choice costs the most, so let me be concrete about my own numbers.

A container's marginal cost is its process RSS. A microVM's marginal cost is a guest kernel plus whatever RAM you allocated the guest — and on Firecracker you cannot change vCPU or RAM at snapshot restore, so the allocation is baked into the template when you build it, not chosen per request. My baked templates: 1 GiB for Postgres, 2 GiB for the agent and code-interpreter templates, 4 GiB for base and browser. Base is 4 GiB because Next.js and TypeScript builds were OOM-killing at 2 GiB, and I had no way to say "just this one gets more." That is a density penalty against gVisor and containers that no amount of tuning recovers. It's the shape of the runtime.

What you can do is stop billing for it. The category converged on active-CPU billing — Cloudflare charges CPU at 10ms granularity while actually running, Vercel bills CPU only when in use, AgentCore is marketed as active consumption on its CPU dimension. But almost everyone still bills provisioned memory for every second the instance is alive. My meter bills working-set memory — resident pages, not the allocation — at $0.0162/GiB-hr alongside $0.054/active vCPU-hr (rate card). That's a partial fix. A 4 GiB template that touches 700 MiB bills for 700 MiB, but it still occupies a slot on the host that a container wouldn't.

The theoretical ceiling on one of my hosts is 16,384 sandboxes, from the /30 subnet space in my network pool. I will never reach it — host RAM binds roughly two orders of magnitude earlier. That gap is the cost of picking a hypervisor, expressed as one number.

Constraint 3: snapshotting is nearly free on some runtimes and structurally hard on others

This is the constraint people notice last and regret most.

A microVM's state is a bounded, serializable object, because the VMM owns the entire machine model: vCPU registers, guest RAM, and a handful of virtio device states. That's it. Firecracker exposes it as an API, which is why every Firecracker platform in the table has a pause/resume story — E2B's pause(), Fly's suspend, Vercel's auto-save on stop, CodeSandbox's memory snapshots. They didn't independently invent a feature. They inherited it from the runtime.

A container's state is a process tree relative to a kernel it doesn't own. Checkpointing means CRIU-style extraction of pids, file descriptors, sockets and mounts, then reinjection into a different kernel where those object identities don't exist. It genuinely ships — Google's Pod snapshots and Modal's memory snapshots both exist — but the semantics are narrower and the failure surface is per-workload rather than per-machine. Which is exactly why container platforms lead with disk snapshots: Modal saves filesystem snapshots as Images, Cloudflare's disk snapshots capture disk state, installed dependencies and modified files. A disk image is a clean object. A live process tree is not.

Isolates get a third answer. V8 startup snapshots are why cold start is sub-millisecond — but that's a heap image at a known point, not "resume my running program with its open sockets."

Forking follows the same logic. Copy-on-write fork of a running machine falls out of the microVM model almost for free: MAP_PRIVATE on the memory file, a reflinked rootfs, done. My same-host fork is 400–750ms and I build fork trees on it; the mechanics are in the copy-on-write fork docs and the restore path in snapshot-restore.

But I want to be precise about what a fork preserves, because I shipped a doc that got this wrong. My fork preserves the disk, not the running process tree. A smoke test proved my own documentation false and I had to correct it — that whole embarrassment is written up here. Assume every vendor's fork claim needs the same test before you design around it.

How to choose

Work the constraints in this order. Each one eliminates faster than the next.

1. What does the model emit? Pure JS/WASM transforms → isolates, and stop reading. Anything involving a package manager, a compiler, a browser or a binary → you need a kernel, and isolates are out.

2. Do you trust the code? Your own first-party code in images you built → containers, best density and tooling. Unreviewed but non-hostile code → gVisor is a serious answer and the density is much better than mine. Hostile-by-assumption, arbitrary, multi-tenant → microVM or Kata.

3. Do you need to pause, resume or fork? If yes, and the state includes memory, a microVM runtime gets you there with far less friction. If disk-level snapshots are enough, container platforms do this well and more cheaply.

4. Where must it run? This is a runtime question disguised as a deployment question. KVM microVMs need bare metal or nested virtualization, which is why several microVM vendors are hosted-only. If BYOC into your own cloud account is non-negotiable, Northflank's Kata/gVisor-per-workload model and Google's Kubernetes-native controller are both better-shaped for that than a Firecracker platform you have to stand up on KVM hosts yourself. The self-host requirements for mine are exactly the friction I'm describing.

5. What's the abuse story? Not a runtime property at all — worth saying because I learned it the hard way. A free-tier account 27 minutes old mined cryptocurrency on my fleet while the isolation boundary held perfectly. Isolation is not an abuse control, and no runtime on this page solves it.

What I'd pick for what

Per-request JS transforms, high fan-out: isolates. Nothing else is in the same cost class, and running a hypervisor for this would be silly.

Agent that runs your own tools on your own images: containers, or gVisor if you want the narrower host surface for a modest density cost. Modal is the strongest option here if you also need GPUs — I have none, and that's a straightforward loss for me, not a positioning statement.

You already run Kubernetes: Google Agent Sandbox. The gVisor-default-with-Kata-option model plus warm pools and an upstream SIG controller is a better fit for a GKE shop than anything I'd sell you, and the add-on itself is reported to carry no extra charge over cluster resources.

You need the sandbox inside a platform you're already on: Cloudflare or Vercel. Both are one import away if you live there, and that convenience is worth more than any runtime argument on this page.

Hostile multi-tenant, arbitrary binaries, and you want the code: E2B or PandaStack. E2B is the more honest recommendation for most teams — their infra repo is Apache-2.0 and published with its development history intact, so you can audit how it was built and who has been working on it. My public repo is a squashed, curated cut with about a dozen commits on main, which means you cannot judge upstream activity from it the way you can judge theirs, and the public cut lags the hosted product. That's a legitimate reason to pick them over me, and I'd rather say it than have you discover it.

Where I'd argue for mine: if you specifically want snapshot-restore on every create (p50 179ms, p99 203ms — the anatomy of that path), fork trees as a first-class primitive, idle billing at genuinely zero, and the option to run the whole thing on your own KVM hosts under Apache-2.0. That's a narrow shape. It's the shape I needed, which is why it exists.

The general lesson is smaller than the table: pick the runtime that matches what your agent actually emits, then accept the constraints it hands you, because you will not engineer your way out of them. Six months confirmed that from the inside.

If you'd rather evaluate the layer above this one, the vendor-by-vendor roundup judges the same platforms as products, the systems-level primer covers what a sandbox is before you pick one, and the agent-cloud map covers the four layers that exist past the sandbox.


Ajay Kumar is an infrastructure engineer with 14 years of experience and the creator of PandaStack, Riff and PandaFlow. He is available for infrastructure consulting — microVM platforms, Firecracker, multi-tenant isolation — at linkedin.com/in/ajay-kumar-devops.

I'm Ajay Kumar — I build and operate PandaStack, an open-source Firecracker microVM cloud for AI agents. Everything above comes from running it in production.

Need this kind of infrastructure work? See what I do or email hello@ajayk.sh.


Keep reading