Firecracker vs gVisor: Sandbox Isolation for Untrusted and Agent-Generated Code

Firecracker vs gVisor: Sandbox Isolation for Untrusted and Agent-Generated Code

Author
Daniel Botha
Daniel Botha
Writer at Fly.io
Published

Firecracker isolates untrusted code by giving it a separate guest kernel inside a hardware-virtualized microVM, while gVisor isolates it by intercepting its system calls in a userspace kernel written in Go, so the two defend against different failures at different costs.


You have code you did not write and cannot review: a customer’s build step, a student’s submission, or the shell command an agent just decided to run after reading a web page. It needs to npm install, clone a repo and call an API, and it must not reach the host kernel or the other tenants on the box. A plain container shares that kernel with all of them.

Two production-grade answers remain. Firecracker is the microVM under AWS Lambda.[1] gVisor lists Google Cloud Run, GKE Sandbox and the code execution inside claude.ai among its users.[2] Which you want depends on what you think the attacker will do.


What Is the Difference Between Firecracker and gVisor?

Firecracker puts a whole kernel between untrusted code and the host; gVisor puts a reimplementation of the kernel’s interface between them, in a process. A Firecracker VM enforces that boundary in hardware with KVM; gVisor has no guest OS at all.

How gVisor Isolates: a Kernel in Userspace

gVisor is an application kernel that implements a Linux-like interface, written in a memory-safe language, Go, and running in userspace.[3] It is not a syscall filter like seccomp-bpf, not a wrapper over firejail or AppArmor, and not a VM in the everyday sense of the word.

Three parts matter. The Sentry is that kernel: it intercepts the sandboxed program’s system calls and answers them itself instead of passing them to the host kernel. The Gofer is a separate host process that mediates all access to filesystem resources, so the Sentry never opens host files. runsc is the entrypoint, and it implements the OCI runtime specification used by Docker and Kubernetes: docker run --runtime=runsc puts a container inside the sandbox,[4] and on Kubernetes a pod selects it with runtimeClassName: gvisor.[5]

How the Sentry catches syscalls is a pluggable platform. systrap, which replaced ptrace as the default in mid-2023, relies on seccomp’s trap feature. The KVM platform instead lets the Sentry act as both guest OS and VMM, leveraging processor virtualization extensions to improve isolation and the performance of address space switches, but there is still no virtualized hardware layer.[6] The production guide recommends KVM on bare metal and systrap inside a VM.[7]

How Firecracker Isolates: a Kernel per Sandbox

Firecracker boots a real guest kernel on KVM and keeps its device model deliberately small: emulated VirtIO net, block and vsock devices, a serial console, and a partial keyboard controller whose only job is to let the guest reset the VM. Seccomp filters limit the host system calls Firecracker itself may make, and in production it is started through a jailer that sets up cgroups and a chroot, drops privileges, then execs Firecracker unprivileged.[8] The microVM vs container comparison covers why that separate kernel changes the boundary.


Which Is More Secure, Firecracker or gVisor?

Firecracker gives the stronger boundary against a kernel exploit, and gVisor a strong one with a much smaller footprint, but “which is more secure” only has an answer once you say what you are defending against.

gVisor’s threat model is a host kernel bug. It was created to provide additional defense against the exploitation of kernel bugs by untrusted userspace code.[9] Untrusted code talks only to the Sentry, and the Sentry itself makes a minimal set of host system calls that excludes creating new sockets, unless host networking is enabled, and opening files, unless directfs is enabled. An attacker has to find a bug in a memory-safe kernel, then something useful to do with the narrow host surface left.

Firecracker’s threat model is that the guest kernel is already gone. The guest runs a real Linux kernel with the usual bug count, and that is fine, because a compromised guest kernel is still a guest. The escape has to go through KVM, then the handful of emulated devices, then the jailer.[8]

The honest caveat is that gVisor does not claim protection against hardware side channels and leans on the host for that, which is equally true of a microVM. Neither primitive substitutes for the rest of the design: what credentials the sandbox holds, what it can reach, and what happens when it is destroyed. The agent sandbox page covers that.


How Do Firecracker and gVisor Compare in Performance?

Firecracker is near-native once the guest is running; gVisor is near-native for CPU work but pays on every system call, which is the difference that decides an agent workload.

Firecracker gVisor
Boundary Separate guest kernel on KVM Userspace kernel (Sentry) in a process
Start Boot under 125 ms; restore from snapshot Process start, no kernel to boot
CPU-bound code Native Native; no instruction emulation
Syscall-heavy code Native inside the guest Every call traverses the Sentry
File I/O virtio-block to the guest kernel Routed through the Gofer
Network virtio-net Own stack, less CPU efficient
Memory per sandbox Under 5 MiB VMM overhead plus the guest kernel Sentry’s fixed cost plus per-resource state
Host requirement KVM and /dev/kvm Any Linux; KVM platform on bare metal

Firecracker and gVisor project documentation: [1] [3] [6] [7] [8] [10] [11]. Checked 2026-09-10.

Cold Start, Warm Pools and Snapshots

Firecracker’s published figures are a boot under 125 ms, under 5 MiB of memory overhead per microVM, and up to 150 microVM launches per second per host.[1] A real deployment rarely pays even the boot. On restore, Firecracker maps the memory file privately and loads pages on demand, with writes going to copy-on-write anonymous memory, so a pool of pre-initialised runtimes is resumed per request instead of booted. One wrinkle: resuming from the same state more than once is considered insecure unless what must stay unique does, including random numbers and seeds, the guest entropy pool and cryptographic tokens.[12]

gVisor has no kernel to boot, so its cold start is a process start, a real advantage for short, bursty work.

Syscall and I/O Overhead in an Agent Loop

gVisor’s performance guide names the structural cost: application system calls must traverse additional layers of software. CPU instructions are not emulated, so a compile runs at native speed, but file operations must be routed through the Gofer, and the network stack is less CPU efficient than the one it replaces.[10] An agent loop is the wrong shape for that: git clone, npm install and a test suite are thousands of small file and socket operations, and each pays the toll. Inside a Firecracker guest those calls hit a normal kernel; the cost moves to the boundary, where bytes cross virtio into the host.


Firecracker vs gVisor vs Docker: When Are Containers Enough?

A plain container is enough when the code is yours, or when the worst case is a mess rather than a breach. The efficiency of a single shared kernel is also the exposure: gVisor’s own framing is that container escape is possible with a single vulnerability.[3] Seccomp narrows what a process can ask the kernel for, but a kernel bug reachable through an allowed syscall is still a host compromise.

If the threat is “the agent might do something stupid, or get prompt-injected into deleting the repo,” a container with scoped credentials and a locked-down network covers most of it. If the threat is “someone is actively trying to break out,” you want a second kernel-sized layer. A virtual sandbox built on either is where code from a customer or an LLM belongs.


Which Should You Choose for an AI Agent Sandbox?

Choose Firecracker when the code is genuinely untrusted or syscall-heavy and you control the hardware; choose gVisor when you are on Kubernetes or inside cloud VMs and want a strong upgrade over containers without a hypervisor. Production splits the same way. AWS Lambda runs on Firecracker,[1] and so does Vercel Sandbox, which gives each sandbox a Firecracker microVM with its own filesystem and network.[13] Google runs gVisor under Cloud Run, GKE Sandbox and App Engine, and gVisor also lists OpenAI, for higher-risk tasks including code execution, and Anthropic, for the code execution inside claude.ai.[2] Modal states that its compute jobs are containerized and virtualized using gVisor.[14]

Pick Firecracker when:

  • the workload is an agent loop of package installs, git operations and test runs, where syscall overhead compounds;
  • you can run on bare metal, or on a provider that does, since Firecracker needs the KVM kernel module and read-write access to /dev/kvm;[11]
  • you want snapshot and restore as the warm-pool primitive.

Pick gVisor when:

  • your platform is Kubernetes and you want isolation as a runtimeClassName rather than a new orchestrator;
  • your hosts are cloud VMs without usable KVM, where systrap runs and Firecracker cannot;
  • the workload is CPU-bound or short-lived and rarely touches the filesystem.

Kata Containers is not a third mechanism. It is a container runtime that builds lightweight virtual machines and supports QEMU, Cloud Hypervisor and Firecracker underneath,[15] which makes it the usual path to a microVM boundary inside Kubernetes. The hosted services that package either primitive are compared on the agent sandbox providers page.

The Part Everyone Converges On: Egress Control

Whichever primitive you pick, the network is what actually stops exfiltration. Agents need pip install and git clone, so a sandbox can be neither air-gapped nor open to the internet. The primitive decides what a breakout costs; an egress allowlist decides what it is worth.


Firecracker and gVisor on Fly.io

Fly.io runs every workload in a Firecracker microVM with its own guest kernel, on physical servers Fly operates, so there is nothing for gVisor to do. The platform architecture docs describe those servers as 8 to 32 physical cores with 32 to 256 GB of RAM, with no cloud VM in between, which is the setup Firecracker wants. A container image is fetched, built into a root filesystem and booted in its own microVM, so the microVM is the boundary.

Fly Machines are those microVMs with a REST API; a stopped one usually starts in well under a second. Sprites are the same substrate arranged for untrusted and agent-generated code: a filesystem that survives sleep, copy-on-write checkpoints to restore after an agent breaks something, and a network policy that is the egress allowlist above, set from outside and read-only from inside.


Frequently Asked Questions

Is gVisor a VM?

No. gVisor is an application kernel: a userspace process implementing a Linux-like interface for the sandboxed program, with no guest operating system and no virtualized hardware. Fly.io does not use gVisor; every Machine and Sprite is a Firecracker microVM with its own guest kernel.

Is Firecracker VM safe?

Yes, for the threat model it was built for. Firecracker runs each workload in a KVM-backed microVM with its own guest kernel, keeps the emulated device model small, restricts its own host system calls with seccomp filters, and is started in production through a jailer that drops privileges. Fly.io runs customer code in these microVMs on its own physical servers, which is how different customers share hardware safely.

What is the main difference between Firecracker and Kata Containers?

Firecracker is a virtual machine monitor; Kata Containers is a container runtime that builds lightweight virtual machines and can use Firecracker, QEMU or Cloud Hypervisor underneath. Kata is the usual way to get a microVM boundary inside Kubernetes. Fly.io does not use Kata; it drives Firecracker directly and exposes the result as Machines and Sprites.

Does gVisor work with Docker and Kubernetes?

Yes. gVisor installs as a Docker runtime named runsc, so docker run –runtime=runsc puts a container inside the sandbox, and on Kubernetes a pod selects it with runtimeClassName: gvisor. Fly.io takes a different route: a container image boots inside a Firecracker microVM with its own kernel, so there is no runtime to swap.

Can I run Firecracker inside a cloud VM?

Only if the VM exposes KVM. Firecracker requires the KVM kernel module and read-write access to /dev/kvm, which is why it is normally run on bare metal. Nested virtualization adds overhead, which is why gVisor recommends its systrap platform inside a VM. Fly.io sidesteps this by running Firecracker on physical servers it operates itself.

How fast does Firecracker boot?

Under 125 milliseconds from the start call to the guest’s init process, with under 5 MiB of memory overhead per microVM and up to 150 launches per second per host. On Fly.io, a stopped Machine usually starts in well under a second; the slow step is the first creation, when the container image is fetched and built into a root filesystem.

What is gVisor’s KVM platform, and is it the same as Firecracker?

No. The KVM platform lets the Sentry act as both guest OS and VMM, using processor virtualization extensions to make address space switches cheaper, but there is no virtualized hardware layer and no guest kernel. Firecracker is a full microVM with a separate guest kernel. Fly.io uses Firecracker, not gVisor.

Does Fly.io wrap my container in gVisor?

No. Fly.io runs each workload in a Firecracker microVM with its own Linux kernel, so the microVM boundary is the isolation. gVisor exists to insulate shared-kernel containers from the host, a problem a Firecracker guest does not have. Sprites add an optional egress allowlist and checkpoints on top of that hardware boundary.


Sources

  1. ^ Firecracker, “Firecracker: Secure and fast microVMs for serverless computing”. firecracker-microvm.github.io. Checked 2026-09-10.
  2. ^ gVisor, “Who’s Using gVisor”. gvisor.dev/users. Checked 2026-09-10.
  3. ^ gVisor, “What is gVisor?”. gvisor.dev/docs. Checked 2026-09-10.
  4. ^ gVisor, “Docker Quick Start”. gvisor.dev/docs/user_guide/quick_start/docker. Checked 2026-09-10.
  5. ^ gVisor, “Kubernetes Quick Start”. gvisor.dev/docs/user_guide/quick_start/kubernetes. Checked 2026-09-10.
  6. ^ gVisor, “Platform Guide”. gvisor.dev/docs/architecture_guide/platforms. Checked 2026-09-10.
  7. ^ gVisor, “Production guide”. gvisor.dev/docs/user_guide/production. Checked 2026-09-10.
  8. ^ Firecracker, “Firecracker Design”. github.com/firecracker-microvm/firecracker/blob/main/docs/design.md. Checked 2026-09-10.
  9. ^ gVisor, “Security Model”. gvisor.dev/docs/architecture_guide/security. Checked 2026-09-10.
  10. ^ gVisor, “Performance Guide”. gvisor.dev/docs/architecture_guide/performance. Checked 2026-09-10.
  11. ^ Firecracker, “Getting Started with Firecracker”. github.com/firecracker-microvm/firecracker/blob/main/docs/getting-started.md. Checked 2026-09-10.
  12. ^ Firecracker, “Firecracker Snapshotting”. github.com/firecracker-microvm/firecracker/blob/main/docs/snapshotting/snapshot-support.md. Checked 2026-09-10.
  13. ^ Vercel, “Vercel Sandbox”. vercel.com/docs/vercel-sandbox. Checked 2026-09-10.
  14. ^ Modal, “Security and privacy at Modal”. modal.com/docs/guide/security. Checked 2026-09-10.
  15. ^ Kata Containers, “Kata Containers: Open Source Container Runtime Software”. katacontainers.io. Checked 2026-09-10.