Best Firecracker Snapshot & Restore Tools (2026)
Firecracker's snapshot/restore is the feature that turns a microVM from 'secure but slow to boot' into 'secure and sub-second to create.' You boot a VM once, freeze its memory and device state to disk, and then thaw that image on demand instead of paying for a kernel boot every time. Simple idea; a surprising amount of tooling has grown around it. In 2026 the question isn't 'can I snapshot a Firecracker VM' — the API has done that for years — it's 'which layer of the stack should I be operating at.' That's what this roundup is about: the raw API, the SDKs and container runtimes, the memory-streaming tricks, the process-level cousin (CRIU), and the platforms that manage the whole lifecycle so you never touch a socket.
The field covered here, from lowest-level to highest: (1) the raw Firecracker snapshot HTTP API and its full-vs-diff modes, (2) firecracker-go-sdk and firecracker-containerd, (3) Kata Containers' snapshotting, (4) userfaultfd-based memory streaming / on-demand paging, (5) CRIU as the process-level contrast, and (6) higher-level platforms — E2B, Modal, and PandaStack (our project) — that own snapshot lifecycle for you. Rather than rank these into a leaderboard that ignores your situation, I'll describe what each actually is and the shape of problem it fits, then let you pick the layer that matches how much control you want to hold.
First, know which layer you're choosing
Almost everything below is ultimately calling the same Firecracker snapshot machinery. What differs is how much of the surrounding lifecycle — capture, storage, transfer, restore, memory paging, network re-plumbing, garbage collection — you're signing up to operate yourself. Get honest about that before comparing anything, because it changes the answer completely. If you're building a VMM research harness, you want the raw API. If you're building a product where 'create a sandbox' has to return in a couple hundred milliseconds and you have no appetite to run an agent fleet, you want a platform. Most of the confusion in this space comes from comparing tools that live on different rungs of that ladder as if they were substitutes.
1. The raw Firecracker snapshot API
This is the foundation everything else sits on. Firecracker exposes snapshot operations over its per-VM HTTP control socket: you pause the VM, ask it to create a snapshot (which writes out a memory file and a VM-state file capturing device and vCPU state), and later build a fresh Firecracker process that loads that pair and resumes. It's a small, deliberate API, and it gives you total control — which is exactly why it's also the most work. You own where the files live, how they move between hosts, how you re-attach networking to a restored guest (the guest wakes up believing it still has its old NICs and MAC addresses), and how you avoid the classic footguns.
Two things about the raw path are worth knowing before you build on it. First, snapshot modes: Firecracker supports a full snapshot (the entire guest memory image) and a diff snapshot (only the memory pages dirtied since a prior point), the latter being much smaller and faster to write but requiring you to layer it back onto a base — great for incremental checkpointing, more bookkeeping to manage. Second, the sharp edges that live in the docs for a reason: a restored VM's guest clock is frozen at snapshot time until you nudge it, and reusing a single snapshot to fan out many clones needs care around anything the guest assumes is unique (entropy, clock, network identity). None of this is a knock on the API — it's a minimal VMM primitive doing exactly what a minimal VMM primitive should. Just don't mistake 'the API can snapshot' for 'snapshotting is solved for my product.'
2. firecracker-go-sdk and firecracker-containerd
One rung up, you stop hand-rolling HTTP calls. firecracker-go-sdk is the official Go client that wraps the Firecracker API — machine configuration, device setup, and the snapshot/restore calls — into typed methods, so you're programming against a library instead of a socket. If you're writing an agent or orchestrator in Go (as much of this ecosystem is), it's the natural building block, and it's what a lot of platforms — ours included — build their lower layers on top of. It still leaves the lifecycle questions (storage, transfer, networking, GC) to you; it just makes the per-VM calls civilized.
firecracker-containerd is a different and heavier proposition: it's a containerd integration that lets you run OCI container images inside Firecracker microVMs, bringing snapshotting into a container-native workflow. If your world is already containerd and Kubernetes and you want microVM isolation without abandoning that tooling, this is the on-ramp — with correspondingly more moving parts to operate. Verify its current snapshot capabilities and status against its own repository, since the containerd-integration space evolves and the exact feature set is version-dependent.
3. Kata Containers snapshotting
Kata Containers runs container workloads inside lightweight VMs and can use Firecracker as one of its hypervisor backends (Cloud Hypervisor and QEMU are others). Its value proposition is Kubernetes-native, OCI-compatible microVM isolation — a RuntimeClass you drop in so pods get a VM boundary transparently. Snapshot/restore in the Kata world is best understood as part of a broader VM-lifecycle story (including templating and fast-start techniques) rather than a single primitive you call, and the specifics depend heavily on the hypervisor backend and Kata version. If your isolation requirement is 'strong sandbox, but it must feel like a pod,' Kata is the natural fit; check the current Kata docs for exactly what snapshot/template features your chosen backend supports, because this is precisely the kind of thing that shifts release to release.
4. userfaultfd memory streaming (on-demand paging)
This isn't a separate product so much as a technique layered onto the restore path, and it's the most interesting frontier in 2026. The problem it solves: a full snapshot's memory image can be multiple gigabytes, and downloading the whole thing before you can resume is often the dominant cost of a cross-host restore. userfaultfd (UFFD) is a Linux kernel facility that lets a userspace handler service page faults. Firecracker can hand its guest-memory faults to such a handler, so instead of loading the entire memory file up front, you resume immediately and fetch pages on demand — from local disk, or increasingly from object storage over the network — only when the guest actually touches them.
The payoff is that 'restore' stops meaning 'download several GB, then start' and starts meaning 'start now, page in the hot set as you go.' The real engineering lives in the surrounding tricks: eliding zero pages so you never fetch memory that's all zeros, recording a prefetch trace of the hot page set at bake time and replaying it in the background so faults become cache hits, and caching fetched chunks per host so the second restore of the same image is local-disk fast. Firecracker's own docs describe the UFFD handoff mechanism; the streaming-from-object-storage layer on top is where platforms differentiate. It's powerful and it's fiddly — a great thing to have built for you unless memory streaming is literally your product.
PandaStack's restore path is built on exactly this. Snapshots are 'thin': agents keep the rootfs local (copy-on-write needs a local block device) but page guest memory on demand from GCS via HTTP Range GET in 4 MiB chunks, with zero-page elision, a baked prefetch trace, a shared per-host chunk cache, and optional 2 MiB hugepages to cut the fault count. The distinction that trips people up: UFFD streams memory, not the disk — the rootfs is always a local file. I'll put the concrete numbers in the PandaStack section below; for every other approach here, the honest move is to measure page-in behavior on your own image and network.
5. CRIU — the process-level cousin (a deliberate contrast)
CRIU (Checkpoint/Restore In Userspace) belongs in this roundup precisely because people keep reaching for it when they mean 'Firecracker snapshot,' and it's a different animal. CRIU freezes and restores a process tree — its memory, open files, sockets — on the host, without a VM in the picture. It's a mature, powerful tool for container live-migration and process checkpointing. But it is not VM snapshotting: there's no guest kernel being frozen, and the isolation properties are those of whatever container the process runs in, i.e. a shared host kernel. If your goal is fast restart of a trusted process or container, CRIU may be exactly right and far lighter than a VM. If your goal is snapshotting an isolated microVM running untrusted code, CRIU is solving a neighboring problem, not this one. Worth knowing so you can rule it in or out fast rather than discovering the mismatch three weeks in.
6. Managed platforms (E2B, Modal, PandaStack)
At the top of the ladder are platforms where snapshot/restore is an implementation detail you never see. You call an SDK method — create a sandbox, snapshot it, fork it — and the platform handles capture, storage, transfer, memory paging, network re-plumbing, and cleanup. E2B and Modal both expose sandbox primitives with their own snapshot/persistence models; describe each in its own docs' terms and verify the current behavior there, since these lifecycle features move quickly and I won't reprint figures I can't stand behind. The trade you're making at this layer is control for convenience: you can't tune the UFFD prefetch trace, but you also don't have to build one. For most people building a product on top of sandboxes, that's the right trade — the snapshot mechanics are load-bearing infrastructure, not your differentiator.
PandaStack (ours) sits here too, with an opinionated design I can be specific about: there is no warm pool of idle VMs. Every create restores a baked Firecracker snapshot on demand, so 'starting a sandbox' is really 'restore memory and resume.' Snapshots and copy-on-write forks are first-class SDK primitives, and the whole thing is open-source and self-hostable on your own KVM hosts. Numbers in the dedicated section below.
The field, at a glance
The short version of each layer, with the shape of problem it fits. Numbers are quoted only for PandaStack; everything else is described qualitatively — verify against its own docs.
- Raw Firecracker snapshot API — what it is: the minimal VMM primitive (create/load snapshot over the HTTP socket, full and diff modes). Best when: you're building a VMM harness or a platform's lowest layer and want total control, and can own storage, transfer, networking, and the frozen-clock footgun yourself.
- firecracker-go-sdk — what it is: the official Go client wrapping the FC API, including snapshot/restore, in typed methods. Best when: you're writing an orchestrator in Go and want a library instead of raw HTTP, but still expect to own the lifecycle.
- firecracker-containerd — what it is: a containerd integration running OCI images inside Firecracker microVMs. Best when: your world is already containerd/Kubernetes and you want microVM isolation without leaving that tooling.
- Kata Containers — what it is: OCI/Kubernetes-native lightweight VMs, Firecracker as one hypervisor backend, with templating/fast-start features. Best when: you need strong isolation that must feel like a pod (a RuntimeClass), not a raw VMM.
- UFFD memory streaming — what it is: a restore technique that pages guest memory on demand (increasingly from object storage) instead of downloading the whole image first. Best when: cross-host restores of large-memory VMs are your bottleneck — and you either build the streaming/prefetch/cache layer or use a platform that has.
- CRIU — what it is: process/container checkpoint-restore on the host, no guest kernel. Best when: you want fast restart of a trusted process or container and don't need VM-grade isolation. Not a Firecracker snapshot substitute.
- Managed platforms (E2B, Modal, PandaStack) — what they are: sandbox APIs that own the entire snapshot lifecycle for you. Best when: sandboxes are your infrastructure, not your differentiator, and you'd rather call sbx.snapshot() than run an agent fleet.
Raw API vs managed SDK, side by side
The clearest way to feel the difference between the bottom and top of this ladder is to look at both. On the left is roughly what the raw Firecracker snapshot dance looks like against the control socket; on the right is the same intent through a managed SDK. The raw calls below are illustrative — field names and endpoints shift across Firecracker versions, so treat this as a shape to verify against the current FC docs, not copy-paste truth.
# --- RAW FIRECRACKER SNAPSHOT API (illustrative; VERIFY fields/paths
# against the Firecracker snapshot docs for YOUR version) ---
API=/run/firecracker.socket # per-VM Unix control socket
# 1) Pause the running VM before capturing a consistent snapshot.
curl --unix-socket $API -X PATCH 'http://localhost/vm' \
-H 'Content-Type: application/json' \
-d '{"state": "Paused"}'
# 2) Create the snapshot: writes a memory file + a VM-state file.
# snapshot_type is "Full" or "Diff" (diff = only dirtied pages).
curl --unix-socket $API -X PUT 'http://localhost/snapshot/create' \
-H 'Content-Type: application/json' \
-d '{
"snapshot_type": "Full",
"snapshot_path": "/snap/vm.state",
"mem_file_path": "/snap/vm.mem"
}'
# 3) Later, in a FRESH firecracker process, load + resume that pair.
# (You still own: moving these files between hosts, re-plumbing the
# guest's network, and correcting the guest clock on resume.)
curl --unix-socket $API2 -X PUT 'http://localhost/snapshot/load' \
-H 'Content-Type: application/json' \
-d '{
"snapshot_path": "/snap/vm.state",
"mem_file_path": "/snap/vm.mem",
"resume_vm": true
}'# --- MANAGED SDK: the whole lifecycle behind three calls ---
from pandastack import Sandbox
# Create = restore a baked Firecracker snapshot on demand.
# ~49ms to restore the snapshot; ~179ms p50 / ~203ms p99 end-to-end.
# Only the very first cold boot of a brand-new template is ~3s.
sbx = Sandbox.create(template="base", ttl_seconds=300)
sbx.exec("pip install pandas && python warm_up.py") # get it hot ONCE
# Snapshot the whole machine (guest memory + rootfs) as a primitive.
snap = sbx.snapshot()
# Fork the running sandbox via copy-on-write: memory shared through
# MAP_PRIVATE, rootfs cloned with a reflink. Same-host fork lands in
# ~400-750ms; cross-host (download + restore) in ~1.2-3.5s.
kids = [sbx.fork() for _ in range(5)] # branch N ways, no re-setup
for k in kids:
k.destroy()
sbx.destroy()Where PandaStack fits (and where I'm allowed to be specific)
To pull it together with the numbers I can stand behind: PandaStack treats snapshot-restore as the boot path, not an optimization. There's no warm pool of idle VMs — every create restores a baked Firecracker snapshot (a snapshot that already holds a booted kernel, a running guest agent, and an open network stack) on demand. That lands at roughly 49ms to restore the snapshot and about 179ms p50 / 203ms p99 end-to-end, with the only slow path being the first-ever spawn of a brand-new template (~3s cold boot, which also bakes the snapshot). Guest memory is streamed on demand from object storage over UFFD — HTTP Range GET in 4 MiB chunks, zero-page elision, a baked prefetch trace, a shared per-host chunk cache, optional 2 MiB hugepages — so a restore begins before the whole memory image is local; the rootfs stays a local copy-on-write file because CoW needs a local block device.
Forking is the other first-class primitive: a fork clones a running sandbox via copy-on-write — guest memory shared through MAP_PRIVATE, rootfs cloned with an XFS reflink — so a same-host fork completes in about 400–750ms and a cross-host fork in roughly 1.2–3.5s. Networking is per-sandbox from a pool of 16,384 pre-allocated /30 subnets per agent, so plumbing a restored guest's network is single-digit milliseconds rather than the cold ~100ms it'd cost to build namespaces and rules from scratch. The whole thing is open-source and self-hostable on any host with /dev/kvm. It's the right pick when you want a Firecracker snapshot platform you can own end-to-end without building the UFFD streaming, fork, and lifecycle layers yourself — and the wrong pick if you specifically need to operate at the raw-API layer for research or a bespoke VMM.
So which do you actually reach for?
Map your situation to the layer, not the reverse:
- Reach for the raw Firecracker API when you're building a VMM harness, doing snapshot research, or writing a platform's lowest layer and need total control — and accept that you own storage, transfer, networking, and the frozen-clock correction.
- Reach for firecracker-go-sdk when you're building that orchestrator in Go and want typed snapshot/restore calls instead of raw HTTP, without giving up control of the lifecycle.
- Reach for firecracker-containerd or Kata when your isolation requirement has to live inside containerd/Kubernetes — OCI images or pods with a microVM boundary — rather than a raw VMM you drive yourself.
- Reach for UFFD memory streaming (build it, or adopt a platform that has) when cross-host restores of large-memory VMs are your specific bottleneck and downloading the full image first is what's slow.
- Reach for CRIU when you actually want process/container checkpoint-restore of trusted code — and don't mistake it for microVM snapshotting.
- Reach for a managed platform (E2B, Modal, PandaStack) when sandboxes are your infrastructure rather than your product, and you'd rather call snapshot()/fork() than run an agent fleet and a memory-streaming pipeline.
The bottom line
There's no single best Firecracker snapshot tool — there's a best layer for how much of the lifecycle you want to hold. The raw API and the Go SDK give you maximum control and maximum operational weight; firecracker-containerd and Kata bring snapshotting into container-native workflows; UFFD streaming is the technique that makes cross-host restore fast if you (or your platform) build the paging layer; CRIU is the process-level cousin you should rule in or out early; and managed platforms hide all of it behind an SDK call. Start from the rung that matches your appetite for owning infrastructure, shortlist two, and measure them on your own image before committing. PandaStack's bet, for the record, is that most teams want snapshot-restore as the default boot path — ~49ms restore, 179ms p50, no warm pool, UFFD streaming and CoW forking built in — on an open-source stack they can run themselves. If that matches your situation, benchmark it against the field and keep me honest.
Frequently asked questions
What is the best tool for Firecracker snapshots in 2026?
There's no universal winner — it depends on which layer you want to operate at. The raw Firecracker snapshot API (create/load over the HTTP control socket, with full and diff modes) gives total control and the most work. firecracker-go-sdk wraps those calls in typed Go methods; firecracker-containerd and Kata Containers bring snapshotting into containerd/Kubernetes workflows. userfaultfd (UFFD) memory streaming is a restore technique that pages guest memory on demand instead of downloading the whole image first. CRIU is a process-level checkpoint/restore cousin, not VM snapshotting. And managed platforms — E2B, Modal, PandaStack — own the whole lifecycle behind an SDK call. Pick the rung that matches how much infrastructure you want to run, then measure your top two on your own image. Verify version-specific details in each project's own docs.
What's the difference between a full and a diff Firecracker snapshot?
A full snapshot captures the entire guest memory image plus VM state, so it's self-contained but larger and slower to write and transfer. A diff snapshot captures only the memory pages dirtied since a prior reference point, so it's much smaller and faster to create — but it isn't standalone; you layer it back onto a base to reconstruct the full state, which adds bookkeeping. Full snapshots suit 'bake once, restore many' patterns; diff snapshots suit incremental checkpointing where a VM is captured repeatedly over its life. Check the exact snapshot_type semantics and any layering constraints in the Firecracker snapshot docs for your version, since API details evolve.
How does userfaultfd (UFFD) memory streaming speed up Firecracker restore?
A full snapshot's memory image can be multiple gigabytes, and loading all of it before you can resume is often the dominant cost of a cross-host restore. userfaultfd is a Linux facility that lets a userspace handler service page faults; Firecracker can hand its guest-memory faults to such a handler. So instead of downloading the whole image up front, the VM resumes immediately and pages are fetched on demand — from local disk or object storage — only when the guest touches them. The real gains come from surrounding tricks: eliding all-zero pages, replaying a prefetch trace of the hot page set, and caching fetched chunks per host. Note UFFD streams memory, not the disk — the rootfs stays a local file because copy-on-write needs a local block device.
Is CRIU the same as a Firecracker snapshot?
No. CRIU (Checkpoint/Restore In Userspace) freezes and restores a process tree — its memory, open files, and sockets — on the host, with no guest kernel involved. Its isolation is whatever the surrounding container provides, i.e. a shared host kernel. A Firecracker snapshot freezes an entire microVM, including its own guest kernel and device state, behind a hardware-virtualization boundary. If you want fast restart of a trusted process or container, CRIU can be exactly right and far lighter than a VM. If you're snapshotting an isolated microVM running untrusted code, CRIU is solving a neighboring problem — reach for Firecracker snapshot/restore instead.
Should I use the raw Firecracker snapshot API or a managed platform?
Use the raw API (or firecracker-go-sdk over it) when you're building a VMM harness, doing snapshot research, or writing a platform's lowest layer and need total control — accepting that you own storage, cross-host transfer, network re-plumbing, and the guest-clock correction on resume. Use a managed platform (E2B, Modal, PandaStack) when sandboxes are your infrastructure rather than your differentiator and you'd rather call create()/snapshot()/fork() than operate an agent fleet and a memory-streaming pipeline. PandaStack, for reference, restores a baked snapshot on every create (~49ms restore, ~179ms p50, no warm pool) with UFFD streaming and copy-on-write forking built in, and is open-source and self-hostable. Verify each platform's current persistence and snapshot semantics in its own docs.
49ms p50 cold start. Fork, snapshot, and scale to zero.