Firecracker vs Flintlock: the VMM vs an orchestrator on it
"Firecracker vs Flintlock" is another comparison that only makes sense once you notice the two live at different layers. Firecracker is a Virtual Machine Monitor — the thing that actually boots and confines a microVM. Flintlock (from the Liquid Metal / Weaveworks lineage) is a service built on top of Firecracker: a gRPC API and daemon that creates, manages, and reconciles Firecracker (and other) microVMs, with containerd doing the image and volume plumbing. Its whole reason for existing is a specific goal — turning bare-metal boxes into a pool of microVMs you can run Kubernetes nodes on. So this isn't "which VMM wins." Flintlock is the orchestrator; Firecracker is the engine underneath it. The useful question is what an orchestration layer like Flintlock adds on top of a raw VMM, and what it is (and isn't) built to give you.
What Flintlock actually is
Firecracker on its own is deliberately low-level. You hand it a guest kernel, a root filesystem, a machine config, and a network tap, and it boots a microVM over a Unix-socket API. It does not pull images, it does not set up networking, it does not track which VMs exist or reconcile them against a desired state. That's the design — Firecracker is a tight, auditable VMM, and everything above it is somebody else's job. Flintlock is one project that takes on that job for a particular use case.
Flintlock's pitch is that you should be able to create and manage microVMs on a bare-metal host the way you'd create and manage containers — through a service with a real API, not by hand-scripting `firecracker` invocations. It exposes a gRPC (and typically an HTTP/gateway) API for the microVM lifecycle: create, get, list, delete. It leans on containerd to handle OCI image content and to store the microVM's volumes and metadata, so the guest's kernel and root filesystem are sourced as images rather than pre-baked disk files you manage yourself. And it's designed to be pluggable at the VMM layer — Firecracker is the flagship backend, but the abstraction anticipates others.
The things it adds on top of Firecracker
- A gRPC service + daemon — a long-running service (`flintlockd`) that owns the microVM lifecycle and answers a typed API, instead of leaving you to drive Firecracker's socket by hand for every VM.
- containerd integration — containerd handles OCI image pulls, content storage, and per-microVM volumes/metadata, so a guest's kernel and rootfs come from images rather than hand-rolled ext4 files.
- Image-based rootfs + kernel — the microVM's disk and kernel are distributed and resolved as OCI artifacts, which fits the container-native supply chain most teams already run.
- A Cluster API (CAPI) MicroVM provider — the payoff use case: a Cluster-API infrastructure provider that provisions microVMs as Kubernetes nodes, so you can stand up self-managed clusters on bare metal / edge hardware where each node is a Firecracker guest.
Read that list and the theme is the same one that shows up under every Firecracker management layer: none of it is virtualization. Every item is API surface, image handling, storage, or cluster provisioning wrapped around a VMM that already knew how to boot a guest. That's not a knock — it's the entire value proposition. Firecracker intentionally stops at the VM boundary, and Flintlock fills in an operational layer above it, tuned for the Kubernetes-node-on-bare-metal shape.
Where Flintlock fits: Kubernetes nodes on bare metal
Flintlock's center of gravity is infrastructure, not application sandboxing. The Liquid Metal story it came from is roughly "bare-metal-as-a-service": you have physical machines, and you want to carve them into strongly isolated microVMs that behave like cloud instances, then run Kubernetes on top with Cluster API driving the whole thing declaratively. In that world, a microVM is a node. Its lifetime is measured in the lifetime of a cluster's node pool, not in the lifetime of a single request. You care about reconciling a desired set of nodes, joining them to a control plane, and replacing them when they fail — classic infrastructure concerns.
That's a legitimate and interesting place to sit, and it's genuinely different from what most people mean when they say "give me a sandbox to run this code." It also means the design optimizes for different things than a per-request workload service would. A node doesn't need to be created in tens of milliseconds; it needs to come up reliably and join a cluster. It doesn't need to be forked; it needs to be reconciled. Those priorities shape everything downstream.
What it does NOT give you out of the box
- Per-request snapshot-restore boot — Flintlock is built around creating and managing microVMs (image-sourced boot), not around snapshotting a booted guest and restoring it in tens of milliseconds on every create. That snapshot-restore-per-create trick is the thing that makes 'a VM per request' cheap, and it's a platform concern, not part of a node-provisioning service.
- A multi-tenant sandbox API — the API is a node/VM lifecycle for infrastructure operators, not a tenant-scoped create/exec/fs/logs surface with auth, quotas, and billing meant to be exposed to end users or agents.
- Fork — copy-on-write cloning of a running microVM's memory and disk isn't the mental model of a Kubernetes-node provisioner; nodes are reconciled and replaced, not cloned mid-flight.
- Managed databases, functions, or app hosting — those are higher-level product surfaces a sandbox platform builds; Flintlock stops at 'here is a managed microVM (and, via CAPI, a Kubernetes node).'
What driving Flintlock looks like
Because Flintlock is a gRPC service, you drive it by describing a microVM and asking the service to create it — either through its API/CLI directly or, more idiomatically, through a Cluster-API resource that names it as the infrastructure provider. The unit you're declaring is a machine, sized and imaged, that will become a node. (Field names, API shapes, and CLI syntax evolve across releases — check the project's docs before running anything.)
# Flintlock is driven as a service: you declare a microVM and the daemon
# creates it via Firecracker, with containerd sourcing the kernel + rootfs
# as OCI images. Illustrative shape only — verify against the project docs.
kind: MicroVM
spec:
vcpu: 2
memoryInMb: 2048
kernel:
# kernel delivered as an OCI image, resolved via containerd
image: "ghcr.io/example/firecracker-kernel:5.10"
filename: "vmlinux"
rootVolume:
# rootfs delivered as an OCI image, not a hand-rolled ext4 file
image: "ghcr.io/example/node-rootfs:ubuntu-24.04"
networkInterfaces:
- type: "macvtap"
# In the Kubernetes use case you rarely touch this directly. A Cluster API
# MicroVMMachine references Flintlock as the infra provider, and CAPI
# reconciles a whole node pool of these into a self-managed cluster.
#
# The unit of work is a NODE with a cluster's lifetime -- not a
# per-request sandbox you create and throw away in milliseconds.Notice what that declaration assumes: a running daemon to own lifecycle, containerd to resolve and store the images, and — in the headline use case — a Cluster API controller reconciling a fleet of these into cluster nodes. That's the orchestration layer talking. Strip it away and you're back to hand-feeding kernel paths and taps to Firecracker's socket. The service is the value; Firecracker is the engine it steers.
Firecracker vs Flintlock, side by side
- What it is — Firecracker: a VMM that boots and confines one microVM. Flintlock: a gRPC service/daemon that creates and manages many microVMs on a host.
- Layer — Firecracker: the isolation primitive (socket API, one guest). Flintlock: an orchestration layer built on that primitive.
- Interface — Firecracker: a per-VM Unix-socket HTTP API you drive yourself. Flintlock: a typed gRPC (and HTTP gateway) API for the microVM lifecycle.
- Image handling — Firecracker: none; you supply kernel + rootfs files. Flintlock: containerd sources kernel + rootfs as OCI images.
- Primary use case — Firecracker: build any microVM system on top. Flintlock: self-managed Kubernetes nodes on bare metal / edge, via a Cluster API MicroVM provider.
- Unit of work — Firecracker: one guest. Flintlock: a managed microVM / cluster node with a node-pool lifetime.
- Snapshot-restore per create / fork — Firecracker: primitives exist in the VMM. Flintlock: not its model — it provisions and reconciles nodes, it doesn't snapshot-restore or fork per request (verify against docs).
Where a sandbox platform like PandaStack differs
PandaStack is a management layer in the same family as Flintlock — it's built on Firecracker, and everything interesting lives above the VMM. The difference is the unit of work it optimizes for. Flintlock's unit is a cluster node with a node-pool lifetime; PandaStack's unit is a sandbox with a per-request (or per-session) lifetime. That single choice cascades into a different design: instead of image-sourced node provisioning driven by Cluster API, every sandbox, managed database, and app is its own Firecracker microVM created via snapshot-restore, exposed through an HTTP/SDK sandbox API rather than a Kubernetes node lifecycle.
In numbers: a create runs at a p50 of about 179ms (roughly 203ms p99), with the restore step itself around 49ms; only the very first cold boot of a template takes about 3s before it's snapshotted, after which every create restores that snapshot. Forking a running VM — a copy-on-write clone of its memory and disk, which a node provisioner has no reason to offer — lands at roughly 400–750ms same-host, or 1.2–3.5s cross-host when the memory has to travel over the network. Networking is pre-allocated for density: each agent carves out 16,384 /30 subnets so a per-VM network namespace + tap can be handed out without paying setup cost on the hot path. And because it's a multi-tenant control plane, it schedules VMs across hosts by scoring live capacity, with auth, quotas, and billing on top — the tenant-facing pieces a node-provisioning service isn't built to expose.
# PandaStack: same family as Flintlock (a management layer on Firecracker),
# but the unit of work is a per-request SANDBOX, not a cluster node --
# so it's an HTTP/SDK API backed by snapshot-restore + a scheduler.
from pandastack import Sandbox
# Create a microVM. Under the hood this is a snapshot-restore of a baked
# template (p50 ~179ms), not an image-sourced cold boot -- the scheduler
# picks a host with capacity and each sandbox gets its own netns + tap.
sbx = Sandbox.create(template="base")
# Run a command inside the hardware-isolated guest.
result = sbx.exec("uname -a && echo hello from a microVM")
print(result.stdout)
# Fork the running VM: a copy-on-write clone of its memory + disk
# (~400-750ms same-host). A node provisioner has no equivalent.
child = sbx.fork()
# Clean up.
child.destroy()
sbx.destroy()So the honest takeaway on "Firecracker vs Flintlock": it was never a head-to-head, because they're not the same thing. Firecracker is the VMM; Flintlock is a gRPC orchestrator built on it, using containerd for images and a Cluster API provider to turn bare metal into Kubernetes nodes. If your problem is "I have physical machines and I want self-managed clusters of strongly isolated nodes," Flintlock's shape is a natural fit — verify its current status first. If your problem is "I want to create and throw away isolated sandboxes per request, with snapshot-restore, fork, and a tenant-facing API," that's a different product shape, and it's the one a sandbox platform is built for. Same engine, different car — and the only real question is which car matches the road you're on.
Frequently asked questions
Is Flintlock a competitor to Firecracker?
No. They sit at different layers. Firecracker is the Virtual Machine Monitor that boots and confines a single microVM over a socket API. Flintlock is a service built on top of Firecracker: a gRPC daemon that creates, manages, and reconciles microVMs, using containerd for OCI image and volume handling. Flintlock uses Firecracker as its engine — it doesn't replace it.
What is Flintlock actually for?
Its headline use case is running Kubernetes nodes on bare metal. Coming from the Liquid Metal / Weaveworks lineage, Flintlock turns physical hosts into a pool of strongly isolated microVMs, and a Cluster API (CAPI) MicroVM provider provisions those microVMs as cluster nodes so you can stand up self-managed Kubernetes on bare-metal or edge hardware. The unit of work is a node with a cluster's lifetime, not a per-request sandbox.
Does Flintlock give me snapshot-restore boot or fork?
Not as its model — verify against the current docs. Flintlock is built around creating and managing (image-sourced) microVMs and, via Cluster API, reconciling them as nodes. It isn't built around snapshotting a booted guest and restoring it per create in tens of milliseconds, nor around copy-on-write forking of a running VM. Those are sandbox-platform capabilities; a node provisioner reconciles and replaces nodes rather than snapshotting or cloning them per request.
How is Flintlock different from a sandbox platform like PandaStack?
Both are management layers on Firecracker, but they optimize for different units of work. Flintlock's unit is a cluster node (image-sourced, provisioned via Cluster API, node-pool lifetime). PandaStack's unit is a per-request sandbox (snapshot-restore create at ~179ms p50 / ~49ms restore, fork at ~400-750ms same-host, an HTTP/SDK API, plus managed databases and app hosting, with multi-tenant auth, quotas, scheduling, and billing). If you want self-managed clusters on bare metal, Flintlock fits; if you want disposable per-request sandboxes with fork and a tenant-facing API, a sandbox platform does.
Is Flintlock still actively maintained?
Flintlock and the broader Liquid Metal project have had maintenance and project-status churn over time, and the API, supported providers, and roadmap evolve. Treat any external summary — including this one — as a point-in-time snapshot and verify the current status, supported versions, and feature set directly against the project's repository, releases, and docs before adopting it or anything built on it.
49ms p50 cold start. Fork, snapshot, and scale to zero.