all posts

Firecracker vs Microsoft Hyperlight, honestly compared

Ajay Kumar··9 min read

"Firecracker vs Hyperlight" is a comparison worth doing carefully, because the two projects share a foundation — both put untrusted code behind a hardware-virtualization boundary on KVM (and Hyper-V on Windows) — but they disagree completely about what to put inside that boundary. Firecracker boots a full, minimal Linux guest: a real kernel, a real init, a real filesystem. Hyperlight, Microsoft's open-source project donated to the CNCF sandbox, throws the guest operating system away entirely and runs a single guest binary — typically a WebAssembly module — directly inside a hypervisor partition, chasing sub-millisecond "cold starts" for per-request function isolation. Same wall, radically different room behind it. This is the honest head-to-head.

We run Firecracker in production; we do not run Hyperlight. Everything about Hyperlight here is described qualitatively from its public design and CNCF materials, and the project moves fast. Treat every Hyperlight claim below as a starting point and verify it against Microsoft's and the Hyperlight project's current documentation before you architect around it. We deliberately invent no Hyperlight benchmark numbers.

What Hyperlight actually is

The usual mental model for a VM is: a hypervisor creates a partition, a guest kernel boots inside it, and your program runs on that kernel. Hyperlight deletes the middle step. It creates a hardware-virtualized partition (via KVM on Linux, Hyper-V/WHP on Windows) and loads a single guest binary straight into that partition's memory — no guest kernel, no guest OS, no boot sequence. The guest is essentially a tiny piece of code with a minimal runtime shim, and the higher-level variant (Hyperlight Wasm) runs a WebAssembly module inside that shim. Because there's no OS to boot, there's almost nothing to start: creating a fresh partition and dropping into guest code is the whole "cold start," which is how the project can talk about sub-millisecond per-call isolation rather than the tens-of-milliseconds a booted or even snapshot-restored VM implies.

The trade that buys is severe and deliberate. With no guest kernel, there are no syscalls in the ordinary sense — the guest can't open a file, bind a socket, fork a process, or run another program, because there is no kernel to service any of that. Instead the guest reaches the outside world only through a small, explicitly-defined host-call interface: functions the host chooses to expose across the partition boundary. That's the same capability-shaped philosophy WebAssembly already has, now enforced additionally by a hardware partition rather than by the WASM runtime alone. The intended workload is small, stateless, per-request functions — the kind of thing you'd otherwise run as a serverless function or an edge worker — where you want a fresh, hardware-isolated instance for every single invocation and you want that instance to cost almost nothing to create.

Hyperlight's guest has no kernel to attack — which is a bold security strategy: bring nothing to the party. It's genuinely elegant. Removing the guest OS removes an enormous amount of code an attacker could pivot through. The catch is that everything the guest can no longer do is also everything your workload can no longer do.

What Firecracker runs, by contrast

Firecracker draws the boundary at the same layer — a KVM-backed partition with a tiny virtio device model facing the host — but fills that partition with a complete minimal Linux guest. There's a real kernel, so there are real syscalls: the guest can fork and exec, spawn a shell, install packages, open files, bind sockets, run compilers, and execute arbitrary unmodified ELF binaries in any language. That's the entire point. Firecracker is what AWS Lambda and Fargate run on, and it's what sandboxing platforms reach for when the code they must run is arbitrary and unpredictable — the defining property of AI-generated code, where a model decides at runtime to `pip install` a package with a native extension and shell out to `git`.

The price for that generality is startup and footprint. A cold Firecracker boot brings up a kernel, which takes real time; and every guest carries the memory cost of a whole OS, not just a function. Firecracker's answer isn't to shed the kernel — it's snapshot-restore: boot the guest once, snapshot its memory and device state, then restore that snapshot on every subsequent create instead of cold-booting. That collapses per-create cost to milliseconds while keeping the full-Linux guest intact. So the two projects attack the same problem — "make a fresh, isolated instance cheap" — from opposite directions: Hyperlight makes the instance cheap by having almost nothing in it; Firecracker keeps everything in it and makes creation cheap by restoring a snapshot.

Side by side

  • Guest kernel — Firecracker: a full, real Linux kernel per microVM, with real syscalls. Hyperlight: no guest kernel and no guest OS at all — just a guest binary (often WASM) in a bare partition.
  • Cold start — Firecracker: ~3s on a first cold boot, but ~179ms p50 / ~203ms p99 when restoring a baked snapshot (PandaStack's measured fast path). Hyperlight: targets sub-millisecond partition creation because there's no OS to boot (qualitative; verify against Microsoft/Hyperlight docs).
  • Workload fit — Firecracker: arbitrary, unmodified, full-OS workloads — any language, subprocesses, package managers, compilers, databases. Hyperlight: tiny, stateless, per-request functions compiled to WASM (or a constrained guest binary) that live entirely within a host-call interface.
  • Statefulness — Firecracker: full filesystem, networking, persistence, snapshots, and long-lived processes. Hyperlight: designed for stateless per-invocation isolation; no OS-level filesystem or process model inside the guest.
  • Isolation model — Firecracker: hardware virtualization (KVM) wrapping a whole guest kernel, plus a jailer + seccomp around the VMM. Hyperlight: hardware virtualization (KVM / Hyper-V) wrapping a single guest binary, with the WASM capability model on top.
  • Maturity — Firecracker: years in production behind Lambda/Fargate and many sandbox platforms; battle-tested. Hyperlight: newer, CNCF sandbox stage, an emerging project rather than a decade-proven runtime (verify current status in its docs).
The maturity and cold-start rows are the ones most likely to shift. CNCF sandbox is an early stage, and "sub-millisecond" is a target shaped by the guest, the host-call surface, and the hardware — not a universal constant. Benchmark Hyperlight on your own workload against its current release rather than trusting any single figure, including the framing here.

The part they agree on: a hardware wall

It's worth being precise about what these two share, because it's the strongest thing they have in common and the reason the comparison is interesting at all. Both use the CPU's virtualization extensions through a hypervisor to create a partition that the host kernel does not directly execute code inside. That's a meaningfully stronger boundary than a container's shared-kernel model or a plain in-process WASM sandbox, because the untrusted code and the host sit in separate address spaces enforced by hardware. Hyperlight's pitch, in fact, is largely "take the WASM security model and add a hardware partition underneath it" — defense in depth for exactly the case where you don't fully trust the WASM runtime alone.

But a hardware boundary is not a magic force field for either project. KVM has had real guest-to-host escape CVEs, and every VMM carries some device-emulation surface. Firecracker keeps that surface tiny (virtio-net, virtio-block, virtio-vsock, a serial console — almost nothing else) and wraps it in a jailer and seccomp. Hyperlight keeps its host-facing surface tiny by having barely any device model at all — its host-call interface is the boundary. Both are "stronger, not immune." Neither should be sold as escape-proof, and anyone who tells you their isolation model has zero attack surface is selling something.

What driving each looks like

Firecracker is driven over a Unix-socket HTTP API, and the minimalism shows up right in the shape of it — a machine config, a boot source, a root drive, and a start action. There's no PCI topology or firmware to wrangle because the device model is deliberately microscopic:

# Firecracker: boot a full Linux guest via its Unix-socket HTTP API.
SOCK=/tmp/firecracker.sock

# vCPUs + RAM — that's the whole machine config.
curl --unix-socket "$SOCK" -X PUT 'http://localhost/machine-config' \
  -H 'Content-Type: application/json' \
  -d '{ "vcpu_count": 2, "mem_size_mib": 1024 }'

# A real kernel image + cmdline — because there IS a guest kernel.
curl --unix-socket "$SOCK" -X PUT 'http://localhost/boot-source' \
  -H 'Content-Type: application/json' \
  -d '{ "kernel_image_path": "./vmlinux", "boot_args": "console=ttyS0 reboot=k panic=1 pci=off" }'

# A root filesystem as a virtio-block device — a whole OS to run against.
curl --unix-socket "$SOCK" -X PUT 'http://localhost/drives/rootfs' \
  -H 'Content-Type: application/json' \
  -d '{ "drive_id": "rootfs", "path_on_host": "./rootfs.ext4", "is_root_device": true, "is_read_only": false }'

curl --unix-socket "$SOCK" -X PUT 'http://localhost/actions' \
  -H 'Content-Type: application/json' \
  -d '{ "action_type": "InstanceStart" }'

Hyperlight is a library you embed in a host program rather than a VMM you boot. Conceptually — and this is illustrative pseudo-code, not the real Hyperlight API, so check the project's SDK for exact types — the host loads a guest binary into a fresh sandbox, registers the handful of host functions the guest is allowed to call, and invokes a guest function. Each call can run in its own fresh partition, which is where the sub-millisecond-per-call story comes from:

// ILLUSTRATIVE pseudo-code — NOT the real Hyperlight API.
// Verify exact types and calls against the Hyperlight docs.

// A fresh hardware partition with NO guest kernel — just this binary.
let mut sandbox = Sandbox::new("./guest_function.wasm")?;

// The guest has no syscalls; it can only call host functions you expose.
// This is the ENTIRE outside world the guest gets.
sandbox.register_host_fn("log", |msg: String| host_log(msg))?;

// Invoke a guest entrypoint. A new partition per call = per-request isolation.
let result: i32 = sandbox.call_guest_fn("handle_request", request_bytes)?;

// There is no `pip install`, no shell, no fork here — by design.
// If the workload needs those, it needs an OS, i.e. the Firecracker case.

The two snippets are the whole philosophy in miniature. Firecracker's API asks "what machine do you want?" — because it's going to run an entire machine. Hyperlight's asks "which functions may the guest call?" — because the guest is a function with nothing underneath it. One is a tiny operating system in a box; the other is a box with no operating system in it.

How to choose

The decision is refreshingly concrete once you frame it as "does the workload need an operating system?" If your untrusted code is a small, stateless, per-request function that you control the compilation of — a rules engine, an edge transform, a plugin, an expression evaluator, a WASM-compiled handler — and you want the densest possible per-invocation hardware isolation with near-zero start cost, Hyperlight is aimed squarely at you, and a full Linux microVM would be over-paying for a kernel you'll never use. If Hyperlight fits, it fits well, and pretending a VM is always the answer would be dishonest.

But the moment the workload needs to be an actual computer — run arbitrary unmodified binaries, `pip install` something with a native extension, shell out, spawn subprocesses, compile code, hold a filesystem, keep state, run a database — Hyperlight's "bring nothing" model can't run it at all, and you need a real guest kernel. That's not a knock on Hyperlight; it's the explicit boundary of its design. This is the AI-agent and general code-execution case, where the whole value proposition is running commands you didn't write and couldn't fully anticipate. You can't compile the future to WASM ahead of time when you don't know what the model will decide to install.

Why PandaStack sits on Firecracker

PandaStack runs on Firecracker because arbitrary, untrusted, model-generated code needs an operating system, not a function shim. Every sandbox is a Firecracker microVM with its own Linux guest kernel isolated by KVM, so a real shell, `pip install` of anything, subprocesses, compilers, and the full long tail of native-dependency Python all just work — none of which lives inside Hyperlight's kernel-less model:

from pandastack import Sandbox

sbx = Sandbox.create(template="code-interpreter")

# Arbitrary native code on a real kernel — the thing a kernel-less
# guest can't run at all. This is exactly the AI-agent workload.
sbx.exec("pip install duckdb pandas")
out = sbx.exec("python -c \"import duckdb; print(duckdb.sql('select 42').fetchone())\"")
print(out.stdout)  # (42,)

# Shell out, spawn subprocesses, compile — all fine with an OS underneath.
sbx.exec("gcc --version && git init /tmp/repo")

The classic objection to the full-VM model is that a whole OS per instance must be slow and heavy — and that's the part the engineering answers. There's no warm pool of idle VMs; every create restores a baked snapshot on demand at ~179ms p50 and ~203ms p99, with only the very first cold boot of a template taking around 3s. A same-host fork branches a running environment via copy-on-write memory plus an XFS-reflink rootfs in roughly 400–750ms; a cross-host fork lands in about 1.2–3.5s. A managed Postgres database, which really does bootstrap a full server, takes 30–90s. Each agent pre-allocates 16,384 /30 subnets so per-sandbox networking is set up in single-digit milliseconds. The core is Apache-2.0 open source and self-hostable on your own Linux KVM hosts.

None of that makes Firecracker the right answer for a tightly-scoped WASM function — if your workload is a stateless per-request handler you compile yourself, Hyperlight's kernel-less partition is a genuinely better-fit tool, and you should use it. It makes Firecracker the right answer for the workload it's actually for: arbitrary code you didn't write and can't fully predict, which needs a whole operating system behind a hardware wall. If you want the deeper version of the kernel-less-vs-full-OS trade-off, the WASM angle is spelled out in our piece on WebAssembly vs Firecracker for untrusted code, and the broader isolation ladder is in microVM vs VM vs container.

Frequently asked questions

What is Microsoft Hyperlight?

Hyperlight is an open-source Microsoft project (donated to the CNCF sandbox) for running a single guest binary — typically a WebAssembly module — directly inside a hardware-virtualized partition with no guest operating system or kernel. Because there's no OS to boot, it targets sub-millisecond partition creation for per-request function isolation. The guest can't make ordinary syscalls; it reaches the outside world only through a small host-call interface the host chooses to expose. Verify current details against Microsoft's and the Hyperlight project's own documentation, since the project is evolving quickly.

What's the core difference between Firecracker and Hyperlight?

What runs inside the partition. Firecracker boots a full, minimal Linux guest — a real kernel, syscalls, filesystem, and processes — so it can run arbitrary unmodified binaries in any language. Hyperlight throws the guest OS away and runs a single guest binary (often WASM) in a bare hardware partition, which lets it start in sub-millisecond time but means the guest has no kernel, no syscalls, no subprocesses, and no filesystem of its own. Both use hardware virtualization (KVM, plus Hyper-V for Hyperlight on Windows); they just disagree about what to put behind the wall.

Which should I use for AI-agent or general code-execution sandboxes?

Firecracker. AI agents run commands you didn't write and can't predict — they pip install packages with native extensions, shell out, spawn subprocesses, and compile code — and all of that needs a real operating system. Hyperlight's kernel-less model deliberately can't run those, so it's the wrong fit for arbitrary code. Firecracker (and platforms built on it, like PandaStack) gives you a full Linux guest behind a hardware boundary, with snapshot-restore keeping per-create cost in the low hundreds of milliseconds.

When is Hyperlight the better choice?

When your untrusted code is a small, stateless, per-request function that you control the compilation of — a WASM-compiled handler, a rules engine, an edge transform, a plugin — and you want the densest possible per-invocation hardware isolation with near-zero start cost. In that case a full Linux microVM would be over-paying for a kernel you'll never use, and Hyperlight's bring-nothing model is a genuinely better fit. Confirm its current capabilities and maturity against the project's documentation before committing.

Is Hyperlight more secure than Firecracker because it has no guest kernel?

Removing the guest kernel does remove a large amount of code an attacker could pivot through, which is a real benefit — but 'no attack surface' is a myth for both. Both rely on hardware virtualization (KVM/Hyper-V), which has had real guest-to-host escape CVEs, and both keep a small host-facing surface (Firecracker a tiny virtio device model plus a jailer and seccomp; Hyperlight a minimal host-call interface). Frame the difference as 'stronger, not immune,' and choose by workload fit and threat model rather than a single security claim.

Run code in a microVM in one API call.

49ms p50 cold start. Fork, snapshot, and scale to zero.

Start free
Written by Ajay Kumar, Founder, PandaStack.