Firecracker vs. Other VMMs

This is the reference you cite when someone asks "why not just use QEMU?" — or when you have to justify, in a design discussion, why a proposed feature belongs (or doesn't) in a VMM whose entire thesis is do almost nothing. It places Firecracker against the rest of the isolation landscape: QEMU, Cloud Hypervisor, gVisor, Kata Containers, runc/containers, and unikernels. The big table is the scannable core; the prose after it explains the trade-offs and where each option actually fits.

Reach for this when you are writing a design justification, reviewing a PR that adds device surface area (minimal-device-model philosophy), or placing Firecracker for a colleague who only knows containers.

Warning: Numbers here are order-of-magnitude and version-sensitive — boot times and memory overheads depend on kernel, config, and workload, and the other projects evolve independently. Cite the shape of the comparison ("microsecond-scale device model, single-digit-MiB overhead, KVM boundary"), not a specific millisecond. Firecracker's own headline claims (≤125 ms to app code, <5 MiB overhead/microVM, >20x oversubscription tested) come from the NSDI '20 paper; verify against the current docs/ and FAQ.md on your branch.


The two questions that organize everything

There are really only two axes, and every row in the big table is a position on them:

  1. What is the isolation boundary? A hardware-virtualization boundary (a real VM, guest kernel included, behind VT-x/AMD-V/ARM-EL2) — or a software boundary (shared host kernel + namespaces, or a userspace syscall-intercepting "kernel")? This decides how strong the isolation is against a hostile guest.
  2. How much machine does the VMM emulate? A full PC (BIOS, PCI, USB, dozens of devices, many architectures) — or the bare minimum a Linux guest needs to boot and do I/O? This decides boot time, memory overhead, and — critically — attack surface, because every emulated device is privileged host code a malicious guest can attack.

Firecracker's answer is hardware boundary + almost no machine. That single combination is its whole identity, and it's what the table below makes concrete.

                 software boundary                      hardware (VM) boundary
                 (shared/userspace kernel)              (KVM / hypervisor)
  full machine                                          ┌── QEMU ───────────────┐
                                                        │  Cloud Hypervisor      │
  ───────────────────────────────────────────────────  ├────────────────────────┤
  minimal      runc/containers   gVisor                 │  Firecracker  (Kata can│
  machine      (namespaces)      (Sentry, userspace)    │  sit under Kata)       │
                                                        └────────────────────────┘

The full comparison

DimensionFirecrackerQEMUCloud HypervisorgVisorKata Containersrunc / containersUnikernels
Isolation modelKVM microVM, minimal devices; guest kernel untrustedKVM (or TCG emulation); full machineKVM / MSHV; rust-vmmUserspace kernel (Sentry) intercepts syscalls; no HW-virt by defaultOCI container inside a lightweight VMLinux namespaces + cgroups; shared host kernelApp + library-OS as one image, in a VM
Boot time≤125 ms to app code100s ms – seconds (firmware/PCI probe)sub-secondcontainer-class (no VM boot)~100s ms (VM + agent + container)fastest (no kernel boot)very fast (tiny image)
Memory overhead<5 MiB / microVM~100+ MiB (firmware, fuller device model)~10+ MiBtens of MiB (Sentry process)VMM + guest kernel + agentlowest (just the process)low (no general-purpose OS)
Device modelvirtio-MMIO net/block/vsock/balloon/rng, serial, i8042-reset; no BIOS/PCI-legacy/USB/GPUhuge: PCI, USB, GPU, SCSI, firmware, many archsmoderate: virtio-PCI, ACPI, hotplug, VFIO passthroughn/a (intercepts syscalls, not devices)inherits its underlying VMM'shost devices directlyonly what the app links
Transportvirtio-MMIO default (virtio-PCI behind --enable-pci)virtio-PCI, emulated legacy busesvirtio-PCIn/ainherits VMMn/avaries
LanguageRust (memory-safe)CRustGoGo (+ its VMM)Go / Cvaries (C, OCaml, Rust, …)
Device/CPU hotpluglimited (memory hotplug emerging — verify)extensive (CPU/mem/PCI hotplug)yes (CPU/mem/device hotplug)n/avia VMMn/a (it's a process)typically none
Live migrationno (snapshot/restore instead)yes (mature)yesno (checkpoint/restore exists)via VMMcheckpoint/restore (CRIU)rarely
Snapshot/restoreyes (full + diff; UFFD lazy load)yes (savevm)yesyes (checkpoint)via VMMCRIUvaries
Attack surfacevery small (minimal devices + Rust + jailer + seccomp)large (huge C device model)moderate (smaller than QEMU, Rust)moderate-novel (the Sentry is the kernel surface)VM boundary + container surfacelargest for hostile guests (shared kernel)small (tiny TCB, but immature tooling)
Primary use caseserverless, multi-tenant, high densitygeneral-purpose virtualizationmodern cloud guests (full-featured VMs)sandboxing semi-trusted containersVM-grade isolation for OCI/K8s workloadscooperative / single-tenant containerssingle-purpose appliances

Where each one actually fits

QEMU — the everything machine

QEMU is the reference against which Firecracker defines itself. It emulates a complete PC: BIOS/UEFI firmware, PCI and USB buses, SCSI, GPUs, sound, dozens of NIC models, and many guest architectures via TCG when there's no KVM. That generality is exactly why people reach for it — it boots almost any OS, including legacy and Windows guests, supports device passthrough and mature live migration, and has two decades of tooling.

Why Firecracker doesn't "just use QEMU": the generality is the cost. Hundreds of emulated devices in C are hundreds of thousands of lines of privileged host code that a hostile guest can attack; firmware and PCI probing add hundreds of milliseconds and tens of MiB before the kernel even starts; and you cannot densely pack thousands of mutually-untrusting tenants per host when each one drags a full machine behind it. For a serverless platform booting short-lived, multi-tenant functions, "QEMU has it" is not an argument — it's a description of the surface area Firecracker deliberately refuses. This is the heart of the minimal-device-model philosophy; internalize it, because it's the maintainers' default answer to feature-creep PRs (maintainer-mindset.md).

Cloud Hypervisor — the close cousin

Cloud Hypervisor is the most important comparison for a Firecracker contributor, because it is the other VMM built on rust-vmm — it shares the same low-level crates (kvm-ioctls, vm-memory, linux-loader, …) Firecracker uses (rust-vmm index). Both are Rust, both ride KVM, both reject QEMU's C device sprawl. The difference is target: Cloud Hypervisor aims at modern, full-featured cloud guests — virtio-PCI, ACPI, CPU/memory/device hotplug, VFIO passthrough, live migration. It is "a clean, modern, secure VMM for general cloud workloads."

Firecracker, by contrast, optimizes ruthlessly for density and minimal surface at the cost of those features. The clean way to hold the two: Cloud Hypervisor is what you build when you want a better QEMU; Firecracker is what you build when you want the smallest possible VM that still boots Linux and does I/O. They are siblings sharing a substrate, not competitors — and contributions to the shared rust-vmm crates benefit both (what-is-rust-vmm.md).

gVisor — a different boundary entirely

gVisor is not the same kind of thing. There is no hardware-virtualization boundary by default; instead a userspace process (the Sentry) implements a Linux-compatible kernel and intercepts the container's syscalls, servicing them itself rather than letting them hit the host kernel. The isolation comes from never giving the workload a real host syscall surface, not from VT-x.

The trade-offs are inverted relative to Firecracker: no VM to boot (so container-class startup), but a large, novel trusted surface — the Sentry re-implements a lot of kernel behavior in Go, and compatibility and the Sentry's own correctness become the security story. It shines for sandboxing semi-trusted containers where you want stronger-than-namespaces isolation without paying for a VM. Firecracker's bet is the opposite: pay for a real (but minimal) VM, and lean on the hardware boundary plus a tiny VMM rather than a large software kernel.

Kata Containers — the integrator, not a competitor

Kata is frequently miscompared to Firecracker; it's actually a consumer of VMMs. Kata runs each OCI container (or pod) inside its own lightweight VM, giving Kubernetes/containerd workloads VM-grade isolation while keeping the container UX. Crucially, Kata can use Firecracker (or Cloud Hypervisor, or QEMU) as its underlying VMM. So "Firecracker vs Kata" is a category error: Kata is the orchestration/runtime layer; Firecracker is one of the engines it can sit on top of. The Firecracker analogue at this layer is firecracker-containerd, which similarly runs OCI containers inside Firecracker microVMs.

runc / containers — the baseline

runc (the OCI runtime under Docker/containerd) is the floor: namespaces + cgroups + seccomp, sharing the host kernel. Fastest startup, lowest overhead, simplest — and the weakest boundary against a hostile guest, because a kernel exploit is a host compromise; there is no second wall. This is precisely the gap Firecracker exists to fill: container-grade density and speed with VM-grade isolation. The whole reason AWS built Firecracker is that for multi-tenant Lambda/Fargate, shared- kernel containers were not a strong enough boundary, and full VMs were too heavy. See the "why Firecracker exists" framing.

Unikernels — the other minimalism

Unikernels chase the same "minimal footprint" goal from the opposite direction: instead of a minimal VMM running a general-purpose kernel, link the application directly with library-OS components into a single bootable image with no general-purpose OS, no shell, no multiple processes. Tiny TCB, fast boot, small image. The cost is the ecosystem: you generally rebuild your app against the unikernel toolchain, debugging and operational tooling are immature, and the model fits single-purpose appliances far better than arbitrary workloads. Firecracker keeps a normal, unmodified Linux guest (any rootfs, any binaries) and puts the minimalism in the VMM, not the guest — which is why it can run unmodified Lambda/Fargate workloads where a unikernel would require porting.


The trade-off in one mental model

   stronger isolation vs hostile guest  ◄──────────────────────────────►  weaker
        full VM            microVM        userspace-kernel      shared-kernel
        (QEMU,             (Firecracker,   (gVisor)             (runc)
         Cloud Hyp.)        Kata-on-FC)

   heavier (boot/mem/surface)  ◄──────────────────────────────►  lighter
        QEMU                Cloud Hyp.      Firecracker / gVisor      runc

Firecracker deliberately sits at the corner almost nothing else occupies: the isolation strength of a VM, near the footprint of a container. It buys that corner by refusing device surface area — which is why, as a contributor, the bar for adding surface is so high. Every device, every API field, every transport is host code that erodes the very property in the bottom-right of the first diagram. When you propose a feature, ask which corner it moves Firecracker toward; if the answer is "toward QEMU," expect resistance, and have a density-or-isolation reason ready.

Note — who runs on Firecracker. The bet has paid off in adoption: AWS Lambda and Fargate, Fly.io, firecracker-containerd, Kata, Vercel Sandbox, Northflank, Koyeb, Qovery, flintlock, and others run multi-tenant or untrusted workloads on it precisely because of the minimal-surface + hardware-boundary combination. That production pressure is why the maintainers guard the surface so hard — it is infrastructure, not a demo.


Quick decision guide

If you need…Reach for…
Densely packed, short-lived, multi-tenant workloads with VM isolationFirecracker
A full-featured modern cloud guest (PCI, ACPI, hotplug, migration), still Rust/minimal-ishCloud Hypervisor
To boot anything (Windows, legacy OSes, exotic devices, passthrough)QEMU
Stronger-than-namespaces sandboxing for semi-trusted containers, no VM bootgVisor
VM-grade isolation for OCI/K8s workloads with container UXKata (on Firecracker / Cloud Hypervisor / QEMU)
Fastest, lightest containers for cooperative / single-tenant coderunc
A single-purpose appliance with the tiniest possible TCB, willing to rebuild the appUnikernel

Next: return to the Appendix index to pick your next reference, or back to the Introduction to re-read the project's thesis now that you can place it precisely in the landscape.