Firecracker vs Hyper-V Isolated Containers: Two Ecosystems, One Verdict
I build PandaStack, an open-source Firecracker microVM platform, so I spend most of my week on the Linux side of this question. But the most interesting thing about container isolation is not anything either ecosystem built — it is that two ecosystems sharing essentially no code arrived at the same verdict within a couple of years of each other, and almost nobody writes that up.
Microsoft shipped VM-backed containers because Windows containers on a shared kernel were not a boundary they were prepared to stand behind for arbitrary multi-tenant workloads. The Linux world shipped Firecracker, Kata Containers and gVisor for precisely the same reason, at roughly the same time, without coordinating. One side wrapped the container in a lightweight utility VM and kept the container API. The other side built a new hypervisor and threw away everything that was not strictly necessary. Same conclusion, opposite directions.
Before any of the comparison: Firecracker is Linux and KVM only. It does not run on a Windows host and it cannot boot a Windows guest. If the thing you need to isolate is a Windows binary — a .NET Framework service, an IIS site, a Windows-only build agent — then Firecracker is not on your shortlist at all, Hyper-V isolation is the answer, and the rest of this post is background reading. I would rather say that in the third paragraph than bury it on page four. What is left is worth reading anyway, because the two designs diverge sharply on the thing that decides whether a kernel per workload is affordable: how you get a fresh kernel without paying for a boot.
Two ecosystems, one verdict
A container is a polite suggestion to a kernel you are sharing with strangers. On Linux that suggestion is assembled from namespaces, cgroups, capabilities and a seccomp filter — all features of the very kernel they are supposed to be protecting. The attack surface is the whole syscall table, and the syscall table is large, actively researched and still growing. None of that is a criticism of containers. It is a statement about what containers are for: packaging and resource control, not adversarial isolation.
Windows had the structurally identical problem with a different vocabulary. Windows containers are built on silos — an extension of job objects plus virtualization of the object namespace, the registry and the filesystem view — and in process isolation mode the container's processes run on the host kernel. Same shape, same consequence: a kernel bug is a tenant boundary bug.
Microsoft's response was a second isolation mode in which each container gets its own kernel inside a lightweight VM, plus fairly direct guidance about which mode to use when you do not trust the workload. The Linux response was three separate projects that each move the boundary somewhere harder: Firecracker and Kata to a hypervisor, gVisor to a userspace kernel reimplementation. Two ecosystems, independently, reached for a kernel per tenant. That agreement is the headline; everything below is engineering detail.
What Windows containers actually do
Process isolation
Process isolation is the Windows analogue of a normal Linux container. The container's processes execute directly on the host kernel, with the namespace and registry virtualization providing the illusion of a private machine. It is the cheaper mode — no second kernel to boot, no second kernel's worth of memory — and on Windows Server it has historically been the usual default.
It also comes with a constraint that does not exist on Linux: because the container runs on the host's kernel, the host OS build and the container image's OS build have to be compatible. The rules have shifted across releases, so treat the specifics as something to look up rather than remember, but the practical effect is stable — you do not get to run an arbitrary Windows base image on an arbitrary Windows host and expect it to work.
Hyper-V isolation
In Hyper-V isolation, each container runs inside its own lightweight VM — Microsoft's term is a utility VM — with its own kernel. The container API you drive it with does not change much; what changes is that a hypervisor now sits between the container and the host kernel, and the container's syscalls land on a kernel that nothing else is using.
Two things make people choose it. The first is the security argument, which is the one everybody quotes. The second is more mundane and probably causes more adoption: because the container brings its own kernel, the host-build-versus-container-build compatibility constraint is relaxed. A fleet that wants a slightly older base image on a newer host has a mode that permits it. That is an operational reason, not a security one, and a lot of Hyper-V isolation in the wild is there because of build skew rather than threat modelling. On Windows client SKUs it has historically been required rather than optional — you did not get process isolation on a desktop — and that too has moved around across releases.
The utility VM is the same machinery as WSL2 and Windows Sandbox
The interesting part of the Windows design is how much of it is one mechanism reused. The API surface that creates and manages these VMs is the Host Compute Service, generally met through its Go bindings in the hcsshim project, which is what containerd on Windows drives underneath. The same utility-VM machinery shows up in places not branded as containers at all: Windows Sandbox is a disposable desktop built on it, and WSL2 runs a real Linux kernel in a lightweight VM on the same foundations.
Linux containers on Windows — the LCOW work, and the WSL2 backend Docker Desktop uses today — is that same trick pointed at a Linux kernel instead of a Windows one. Which is the quiet punchline of this comparison: when Windows needs to run Linux containers, it boots a Linux kernel in a VM, because that is the only way to get Linux syscalls. The boundary was never optional. It was just differently priced.
The tradeoff is exactly what you would expect and it is worth stating plainly rather than hedging: more isolation, more memory per container, slower start, and a second kernel per container that someone has to boot and patch. You have traded a packaging primitive for a virtualization primitive, and virtualization primitives cost RAM.
What Firecracker does differently
Firecracker started from the opposite end. Instead of taking a general-purpose hypervisor and making it light enough to put under a container, it is a purpose-built VMM written in Rust whose design premise is that you do not need most of a virtual machine. There is no BIOS and no legacy boot path — the VMM loads an uncompressed kernel directly. The device model is deliberately tiny: virtio block, virtio net, virtio vsock, a serial console, a keyboard controller that exists mainly so the guest can be told to reboot. No emulated graphics adapter, no sound card, no USB controller, no CD-ROM.
Around that sits a defence-in-depth story aimed at the host: a jailer that chroots and drops the VMM into its own namespaces and cgroup before handing over control, and a seccomp filter reducing the host-side VMM process to a short list of permitted syscalls. The threat model is explicit — you are protecting the host from a guest already assumed compromised.
On PandaStack that is Firecracker v1.16.0, a 5.10 guest kernel, and an Ubuntu 24.04 userland inside the guest. Host needs KVM. One thing worth noticing: because the guest brings its own kernel, there is no equivalent of the Windows build-compatibility constraint at all. The guest kernel version is a property of the template, not of the host distribution, and I can change one without touching the other. If you have fought Windows container base-image compatibility, that decoupling is the thing you would actually enjoy.
Snapshot restore is the part that actually matters
A tiny device model makes boots fast. Snapshot restore makes boots unnecessary, and that is the difference that changes the economics. Firecracker can serialize a running VM's memory and device state and restore it later, which means a fresh kernel per workload stops being something you boot and becomes something you un-pause.
PandaStack restores a baked template snapshot on every single create: p50 179 ms, p99 203 ms, with no warm pool of idle VMs anywhere in the system. The only slow path is the very first spawn of a template that has no snapshot yet, which cold-boots in roughly 3 seconds and bakes the snapshot on the way through, after which every subsequent create takes the restore path. Memory comes back as a private mapping so the kernel does copy-on-write on fault, or — when streaming is turned on — through a userfaultfd handler that pages 4 MiB chunks out of object storage on demand. The rootfs is a block device with copy-on-write underneath it (XFS reflink or dm-snapshot) and is always a local file, because CoW needs one. Streaming covers memory only. There is a longer write-up of that path at The Snapshot-Restore Boot Path: Every Sandbox in Under 200ms.
Since I am being honest about limits: restore has sharp edges and I have been cut by them. A restored guest resumes with whatever clock it had at bake time, which for a while meant guests failing TLS handshakes with certificate-not-yet-valid errors — a genuine incident, now fixed by force-syncing the clock on restore, resume and wake. Snapshots also freeze vCPU count and RAM, because Firecracker cannot change either at restore, so per-create `cpu` and `memory_mb` are overridden to whatever the template baked. RAM is the only template knob: `base` and `browser` 4 GiB, `code-interpreter` and `agent` 2 GiB, `postgres-16` 1 GiB, all at 8 vCPU.
# ---------------------------------------------------------------------------
# The Windows side. Two ways to ask for a kernel per container.
# Verify every flag and path against Microsoft's current docs -- this area has
# been renamed and re-defaulted more than once.
# ---------------------------------------------------------------------------
# 1. The one-liner. --isolation picks the MODE, not the image.
# "process" -> container processes run on the HOST kernel (Linux-container
# shaped). Cheapest. Requires host build and container-image
# build to be compatible -- this is the constraint that bites.
# "hyperv" -> container runs inside its own lightweight utility VM with
# its own kernel. More RAM, slower start, boundary is the
# hypervisor instead of the shared kernel.
# "default" -> whatever the daemon's default is for this SKU. On Windows
# Server that has historically been process; on client SKUs
# hyperv has historically been required. Do not rely on
# "default" meaning the same thing on two machines.
docker run --rm --isolation=hyperv mcr.microsoft.com/windows/servercore:ltsc2022 \
powershell -Command "Get-ComputerInfo | Select-Object OsBuildNumber"
# The same image under process isolation is the compatibility test: if the host
# build and the image build are not compatible, THIS is the one that fails and
# the hyperv run above is the one that works. That is why a lot of production
# Hyper-V isolation exists -- not threat modelling, just build skew.
docker run --rm --isolation=process mcr.microsoft.com/windows/servercore:ltsc2022 \
powershell -Command "Get-ComputerInfo | Select-Object OsBuildNumber"
# 2. The containerd shape. Isolation is selected by RUNTIME HANDLER rather
# than a CLI flag, so the decision moves into cluster config -- a RuntimeClass
# in Kubernetes terms. Sketch of config.toml; check the current schema.
cat <<'TOML'
[plugins."io.containerd.grpc.v1.cri".containerd]
# Which handler a pod gets when it does not ask for one by name.
default_runtime_name = "runhcs-wcow-process"
# Process isolation: no utility VM. The shared-kernel option.
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runhcs-wcow-process]
runtime_type = "io.containerd.runhcs.v1"
# Hyper-V isolation: one utility VM per container, driven through HCS via
# hcsshim. The sandbox_isolation knob is what flips it; the options table is
# also where utility-VM sizing (CPU count, memory) lives -- and utility-VM
# memory is the per-container overhead you are buying.
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runhcs-wcow-hypervisor]
runtime_type = "io.containerd.runhcs.v1"
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runhcs-wcow-hypervisor.options]
sandbox_isolation = 1
TOML
# Note what did NOT change in either case: the image, the registry, the build,
# the orchestrator, the people. That low adoption friction is the single
# strongest argument for Hyper-V isolation and I am not going to pretend
# otherwise -- standing up a Firecracker fleet is a much larger project.
# ---------------------------------------------------------------------------
# The Firecracker side. This is the entire machine. Look how little there is.
# ---------------------------------------------------------------------------
cat > /tmp/vm.json <<'JSON'
{
"boot-source": {
"kernel_image_path": "/var/lib/pandastack/kernels/vmlinux-5.10",
"boot_args": "console=ttyS0 reboot=k panic=1 pci=off nomodules random.trust_cpu=on init=/sbin/init"
},
"drives": [
{
"drive_id": "rootfs",
"path_on_host": "/var/lib/pandastack/vms/abc123/clone.ext4",
"is_root_device": true,
"is_read_only": false
}
],
"network-interfaces": [
{
"iface_id": "eth0",
"host_dev_name": "tap0",
"guest_mac": "06:00:ac:10:00:02"
}
],
"machine-config": {
"vcpu_count": 8,
"mem_size_mib": 4096,
"smt": false
}
}
JSON
# What each piece is doing, and what is conspicuously absent:
#
# kernel_image_path An UNCOMPRESSED kernel loaded directly by the VMM. There
# is no BIOS, no UEFI, no bootloader, no option ROM. The
# whole legacy boot path that a general-purpose hypervisor
# carries simply does not exist here. 5.10 on PandaStack.
#
# boot_args pci=off is the tell: there is no PCI bus to enumerate,
# because every device is virtio-over-MMIO. nomodules means
# the guest will not go hunting for hardware that is not
# there. reboot=k + panic=1 make the guest DIE rather than
# sit at a prompt -- the correct behaviour for something
# disposable.
#
# drives One ext4 block device. On PandaStack clone.ext4 is a
# copy-on-write clone (XFS reflink or dm-snapshot) of the
# template rootfs, which is why creating one is O(metadata)
# instead of O(gigabytes). It must be a LOCAL file -- CoW
# needs a local block device, so this is the one artifact
# that cannot be streamed from object storage.
#
# network-interfaces One tap device, living in a per-sandbox Linux network
# namespace with its own veth pair. Pre-allocated, so the
# create path only patches a MAC instead of building
# namespaces from scratch.
#
# machine-config vcpu_count and mem_size_mib. These are FROZEN into any
# snapshot taken of this VM -- Firecracker cannot change
# either at restore time, so a per-create memory request
# against a snapshot-backed template is overridden to the
# baked value. RAM is a template property, not a call
# parameter.
# Boot it with no API server at all -- a config file and one process.
firecracker --no-api --config-file /tmp/vm.json
# There is no GPU line, no PCI passthrough line, no nested-virtualization line,
# and no sound/USB/CD-ROM. That is not an oversight, it is the product.
The comparison, graded on the axes that decide it
| Dimension | Hyper-V isolated containers | Firecracker microVMs |
|---|---|---|
| Isolation boundary | Hypervisor. One lightweight utility VM per container, its own kernel. This is the point of agreement, not the difference. | Hypervisor. One microVM per sandbox, its own kernel, plus a jailer and a seccomp-filtered host process. |
| Guest OS | Windows, from Windows container images. Pointed at a Linux kernel instead, the same machinery gives you LCOW and the WSL2 backend. | Linux only. No Windows guests, ever. This is usually the whole decision and everything else is a detail. |
| Host OS required | Windows with Hyper-V enabled. On client SKUs this mode has historically been mandatory rather than optional. | Linux with KVM. Does not run on a Windows host at all. |
| Start shape | Boot a utility VM per container. Microsoft has invested heavily in making that fast; treat the current numbers as theirs to publish and verify them. | Restore a baked snapshot, not a boot: p50 179 ms, p99 203 ms on every create, no warm pool. ~3 s only for the first spawn of an unbaked template. |
| Memory per instance | A second kernel's worth on top of the workload, per container. Qualitatively and unavoidably higher than process isolation; utility-VM sizing is a config knob. | Baked into the template and fixed at restore: base 4 GiB, browser 4 GiB, code-interpreter and agent 2 GiB, postgres-16 1 GiB, all 8 vCPU. |
| OS build compatibility | A real constraint under process isolation; relaxed under Hyper-V isolation because the container brings its own kernel. One of the main practical reasons people switch modes. | Not a thing. The guest kernel (5.10) and userland (Ubuntu 24.04) are template properties, fully decoupled from the host distribution. |
| Image and disk model | Windows container layers from a registry. Windows base images are large, and that size shows up in pull time, disk and cache strategy. | An ext4 rootfs block device plus copy-on-write (XFS reflink / dm-snapshot), always local. Cloning is O(metadata). Completely different economics. |
| Adoption friction | A flag on a runtime you already run: --isolation=hyperv, or a containerd runtime handler selected per workload. Genuinely the lower-friction story and I will concede it plainly. | A new substrate: KVM hosts, jailer, a pre-allocated network-namespace pool, a snapshot store. Either a platform team's project or somebody else's managed service. |
| What you give up | Density and start latency versus process isolation, plus a second kernel per container to patch and account for. | A minimal device model on purpose: no GPU passthrough, no arbitrary PCI hotplug, no nested virtualization inside the guest, no emulated legacy hardware. |
Latency shape and density are the same conversation
The two rows people stare at are start latency and memory, and they are both consequences of one choice: whether a kernel is something you boot or something you restore.
If a kernel is something you boot, your cost model is per-boot and your optimisation is to make the boot faster — which Microsoft has clearly spent real engineering on for utility VMs. There is a floor to that, because a boot is a kernel doing actual work, and the floor is why the two isolation modes still feel different in a tight loop. If a kernel is something you restore, the per-instance cost is reading back a memory image, which is a different curve entirely: dominated by page faults rather than kernel initialisation, and page faults are exactly what copy-on-write and demand paging are good at.
That is why PandaStack has no warm pool. A warm pool is a workaround for an expensive create, and when the create is a 179 ms restore the pool is just idle RAM with a scheduling problem attached. The flip side is that the restore model only works if you were willing to bake a template in advance, which is a constraint that the flag-on-your-existing-runtime approach does not impose on you.
On density, both worlds hit the same wall and it is RAM. A second kernel per tenant costs memory in Hyper-V isolation and it costs memory in Firecracker, and no amount of clever VMM design makes a guest's resident set go away. PandaStack's hard ceiling is 16,384 pre-allocated /30 subnets per agent host, a number you will never reach, because memory and CPU bind long before the subnet space does. The levers that actually move density are copy-on-write page sharing on restore and an idle clock aggressive enough to delete things — not the hypervisor. MicroVM Density: The Economics of Per-Tenant Isolation is the long version.
Which should you actually pick
This one resolves more cleanly than most head-to-heads, because the guest OS is a hard gate rather than a preference.
- Your workload is Windows. Firecracker is not an option — not a bad option, not an option. Hyper-V isolation is the answer, and the secondary benefit you will probably value more day to day is the relaxed host-to-container build compatibility.
- Your workload is Linux, you need a real multi-tenant boundary, high density and sub-second starts, and the creator of the sandbox is a program rather than a person. Firecracker-class microVMs. That is the case the snapshot-restore model was built for, and it is what I build.
- Your workload is Linux but you want to keep your existing container runtime and orchestrator. Kata Containers runs your OCI containers inside a VM with a shim that speaks CRI, which is the closest Linux analogue to Hyper-V isolation as an adoption story. gVisor takes the other road entirely and intercepts syscalls in a userspace kernel, trading some compatibility for no hypervisor requirement. Firecracker vs Kata vs gVisor: three isolation models grades all three properly.
- You need both Windows and Linux isolated workloads. You need two fleets, and you should plan and budget for two fleets rather than hunting for the substrate that covers both. It does not exist. A Linux host can run a Linux kernel in a VM, a Windows host can run a Windows or a Linux kernel in a VM, and neither can run the other's kernel on bare metal. Pretending one platform covers both is how you end up with a Windows build agent nobody wants to own.
And the honest non-recommendation: if your containers all run code your own team wrote, your tenants are not adversarial, and your compliance story does not require a hypervisor boundary, process isolation on Windows or a plain container on Linux is the right call and the VM is a tax. The verdict both ecosystems reached was about hostile or unvetted code. It was never "VMs for everything."
What the managed version looks like
The reason Hyper-V isolation adopts so easily is that somebody else already runs the hypervisor for you — it ships in the OS. The equivalent on the Firecracker side is a platform. Here is the same shape as that config file, with the fleet, the jailer, the netns pool and the snapshot store already somebody's job.
# The managed version of "give this workload its own kernel."
# Linux guests only -- there is no Windows path here and there will not be one.
from pandastack import Sandbox
# create() is a SNAPSHOT RESTORE, not a boot. The template was baked once; this
# call reads back its memory image and resumes it. p50 179 ms, p99 203 ms, and
# there is no warm pool behind it -- every create takes this same path. The one
# exception is the very first spawn of a template with no snapshot yet, which
# cold-boots in ~3 s and bakes the snapshot on the way through.
#
# cpu and memory_mb are NOT passed on purpose: `base` bakes at 4 GiB / 8 vCPU,
# and Firecracker cannot change either at restore, so a request would be
# overridden to the baked values anyway. RAM is a template knob, not a call arg.
sbx = Sandbox.create(
template="base",
ttl_seconds=600, # IDLE clock, not a wall clock. Anything that
# touches the guest resets it; read-only status,
# metrics and log GETs deliberately do not. When it
# expires the reaper DELETES the VM -- unpushed work
# dies with it unless you passed persistent=True,
# raised the TTL, or snapshotted first.
metadata={"job": "untrusted-build", "tenant": "acme"},
)
try:
# One kernel, one tenant, one job. The guest is Ubuntu 24.04 userland on a
# 5.10 kernel that nothing else on this host is sharing -- which is the
# whole point, and the same point Hyper-V isolation is making on Windows.
print(sbx.exec("uname -r").stdout.strip()) # 5.10.x
# Anything slow or hostile gets fenced IN-GUEST. One-shot exec() does not
# actually enforce timeout_seconds, and exec_stream only widens the HTTP
# timeout -- so timeout(1) inside the guest is the only real bound.
rc = sbx.exec_stream(
"cd /work && timeout --kill-after=10s 900 sh -c 'make -j8 test'",
on_stdout=print,
on_stderr=print,
)
print("exit", rc)
# A kernel boundary is not a network policy. Egress to the internet is OPEN
# by default. Sibling sandboxes cannot reach each other's subnets and the
# cloud metadata range is dropped at the host, but fencing your own VPC,
# databases and internal APIs is still your work. Same on Windows: a
# utility VM does not firewall your intranet for you.
finally:
# Unconditional teardown. kill() -- there is no sbx.delete(). Write this
# even though the idle reaper would eventually do it: "eventually" is a
# billing decision you are making on behalf of your finance team.
sbx.kill()
The bottom line
Two ecosystems that share no code, no leadership and no release calendar both concluded that a shared kernel is not a boundary you can sell to a multi-tenant customer, and both shipped a kernel per tenant. Microsoft did it by wrapping the existing container in a utility VM so the container API survived, which is the lower-friction engineering and the reason Hyper-V isolation is a flag rather than a migration. Firecracker did it by building a new VMM with almost no device model and then making the boot unnecessary through snapshot restore, which is the higher-ceiling engineering and the reason a kernel per request is affordable at all.
Pick on guest OS first, because that gate is absolute. Then pick on who you want running the hypervisor. If you are on Windows, I have nothing to sell you and I would not pretend otherwise. If you are on Linux, want a kernel per workload, and would rather not build a Firecracker fleet yourself, that is what PandaStack is: one microVM per sandbox, snapshot-restored at p50 179 ms with no warm pool, 8 vCPU of burst and the template's baked RAM, at $0.054 per vCPU-hour and $0.0162 per GiB-hour on one rate card. No GPU, no Windows guests, no nested virtualization, egress open until you close it. If any of those four is a requirement, I am the wrong substrate and you should go read somebody else's comparison.
Frequently asked questions
Can Firecracker run Windows?
No, and not in a "not yet" way — in a structural way. Firecracker is a Linux-only VMM that runs on KVM, so it does not execute on a Windows host at all, and its guest side is just as closed: there is no BIOS, no UEFI firmware, no emulated PCI bus, no VGA adapter, no IDE or SATA controller, and no ACPI story of the kind a Windows installer expects. The guest is loaded as an uncompressed Linux kernel image by the VMM directly, which is a Linux boot protocol, not a general-purpose one. A Windows kernel has nothing to attach to. You cannot patch around this with drivers either, because the missing pieces are the firmware and the device model, not the guest drivers. If you need isolated Windows workloads, the answer on a Windows host is Hyper-V isolated containers for container-shaped work or full Hyper-V VMs for everything else; on a Linux host it is a general-purpose hypervisor such as QEMU/KVM with proper firmware, which can boot Windows guests but gives up most of what makes Firecracker fast. That tradeoff is the subject of /blog/firecracker-vs-qemu. Plan for two fleets rather than one substrate.
What is the practical difference between process isolation and Hyper-V isolation on Windows?
In process isolation the container's processes run on the host's kernel, with the Windows silo mechanism virtualizing the object namespace, registry and filesystem view to give the illusion of a private machine. It is cheaper — no second kernel, no second kernel's memory — and on Windows Server it has historically been the usual default. In Hyper-V isolation each container runs inside its own lightweight utility VM with its own kernel, so the boundary moves from the shared kernel to the hypervisor. The security consequence is the one everybody quotes: in process isolation a Windows kernel vulnerability is a tenant-boundary vulnerability, and in Hyper-V isolation it is not, because the kernel the container is attacking is one nothing else uses. But the reason I see teams switch most often is not security at all — it is that process isolation imposes a compatibility relationship between the host OS build and the container image's OS build, and Hyper-V isolation relaxes it, because the container supplies its own kernel. The cost is memory per container, a slower start, and a second kernel per container to patch. Defaults and compatibility rules have genuinely changed across Windows releases, so check Microsoft's current documentation rather than trusting any blog post, this one included.
Is a utility VM the same thing as a microVM?
Architecturally they are extremely close, and the fact that two ecosystems converged on the same shape independently is the most interesting thing about this comparison. Both are a stripped-down virtual machine whose job is to hold exactly one workload's kernel, booted and torn down programmatically by a runtime rather than managed as a long-lived server. Both use paravirtualized devices rather than emulating real hardware. Both are driven through an API by a container-shaped control plane. Where they differ is lineage and therefore priorities. The utility VM is Hyper-V machinery reused — the same foundations under Windows Sandbox and WSL2 — reached through the Host Compute Service and its hcsshim bindings, with containerd on Windows driving it, and its priority was keeping the container experience intact. Firecracker was written from scratch in Rust with the explicit goal of deleting everything a serverless workload does not need, which is how you end up with no BIOS, five or so devices, a jailer and a seccomp-filtered VMM process. The practical consequence of that difference shows up in snapshotting: Firecracker's snapshot-restore path is a first-class feature that platforms build their whole create path on, which is how you get a fresh kernel in 179 ms instead of booting one.
Does Hyper-V isolation or a microVM actually stop container escapes?
It moves the target, which is the honest way to describe it. A container escape on a shared kernel means exploiting the kernel you share with every other tenant on the box, and the surface is the whole syscall table plus the namespace, cgroup and filesystem machinery around it. With a kernel per tenant, compromising the guest kernel gets the attacker root in a VM holding nothing but their own workload; to reach a neighbour they now have to break the hypervisor, a far smaller and far more deliberately hardened surface. Smaller is not zero. Hypervisor vulnerabilities exist, and side channels through shared CPU microarchitecture are a real category that a VM boundary does not fully close. Which is why both ecosystems layer defences rather than relying on the boundary alone: Firecracker adds a jailer that chroots and namespaces the VMM plus a seccomp filter restricting the VMM's own syscalls, on the premise that the guest is already compromised and the host is what you are protecting. And none of it is a network policy. On PandaStack egress to the internet is open by default — siblings cannot reach each other's subnets and the metadata range is dropped at the host, but your VPC and internal APIs are still your job. /blog/controlling-network-egress-untrusted-code covers that half.
If Hyper-V isolation is just a flag, why would anyone build on Firecracker instead?
Because the flag is the right answer for Windows workloads and does not exist for Linux ones, and because the two are optimised for different create rates. Hyper-V isolation is superb when you already run Windows containers and want a stronger boundary without changing your images, registry, build or orchestrator — that low adoption friction is real and I concede it in the post rather than arguing with it. But it is Windows hosts and Windows guests (or a Linux kernel in a utility VM via the LCOW and WSL2 path), so if your workload is Linux you are not choosing between these two at all; you are choosing between Firecracker, Kata, gVisor and a plain container. Within that Linux set, the reason to reach for Firecracker specifically is create rate and density. Snapshot restore means a fresh kernel is a 179 ms memory-image read rather than a boot, with no warm pool to miss, which makes a kernel per request — per pull request, per agent step, per untrusted upload — economically sane in a way that booting a VM per request is not. If your create rate is low and your workloads are long-lived, that advantage mostly evaporates and Kata's keep-your-runtime story is probably the better purchase.
Keep reading
- Firecracker vs Kata vs gVisor — The Linux-side equivalent of this whole argument, including Kata as the closest analogue to Hyper-V isolation's adoption story.
- Firecracker vs QEMU — What you trade away to get a VMM with no BIOS and five devices — and the hypervisor you actually want if you need to boot Windows.
- Firecracker vs Docker — The shared-kernel question stated plainly, without the Windows vocabulary in the way.
- Firecracker vs Apple Containerization — A third ecosystem reaching the same verdict: Apple also decided containers get their own lightweight VM.
- MicroVM vs VM vs container — Where a utility VM and a microVM sit on the same axis, and what each one actually costs per instance.
Related posts
- Snapshot Restore vs Container Image Pull: Two Ways to Start Fast
Your container started in 200ms and then spent nine seconds importing pandas, which is a kind of performance. Lazy pulling attacks the bytes; snapshot restore attacks the part that actually costs you — a process that has already finished initializing.
- Firecracker vs Nabla Containers: two ways to cut kernel risk
Nabla Containers narrow the host kernel attack surface to roughly seven syscalls without a hypervisor. Firecracker takes the hardware-virtualization route instead. Same enemy — the shared host kernel — two very different walls, and only one runs code you didn't build ahead of time.
- Firecracker vs Bottlerocket: One Is a Hypervisor, One Is a Host OS
These two aren't rivals; they're stacked. Bottlerocket hardens the host you share. Firecracker removes the sharing. If you're running untrusted code, that distinction is the whole ballgame.
- Multi-Tenant WordPress Hosting on Firecracker MicroVMs
WordPress is a plugin-execution engine wearing a CMS costume, which makes shared hosting a multi-tenant remote code execution service with good branding. A look at why the PHP hardening stack is not a boundary, and what changes when every site gets its own kernel.
- The Anatomy of a Sub-200ms MicroVM Create
179ms p50 is not a single event — it's eight stages, each shaved to single- or low-tens of milliseconds. This is the itemized bill: where every millisecond of a snapshot-restore create actually goes, and the idea that makes each line cheap.
More in Firecracker & microVMs · See Firecracker microVM sandboxes
49ms p50 cold start. Fork, snapshot, and scale to zero.