MicroVM Use Cases: What Firecracker Is Actually For (2026)
MicroVMs sound like an exotic infrastructure curiosity until you realize you've almost certainly run code inside one this week. Every AWS Lambda invocation lands in a Firecracker microVM. So does a lot of Fargate. The whole category exists because a small set of workloads share one awkward property: you want to run code you don't fully trust, you want it isolated by hardware, and you want it to start in milliseconds — three goals that historically you could pick two of, never all three. A microVM is the design that finally gets all three at once. This post is the definitive rundown of where that trade actually pays off: the real-world use cases a Firecracker-class microVM is built for, and why a plain container falls short in each.
If you want the conceptual grounding first — what a microVM is, how it differs from a container and a classic VM — start with /blog/what-is-a-microvm and /blog/firecracker-vs-docker, then come back here for the catalog. I'm Ajay; I build PandaStack, an open-source Firecracker microVM platform, so I'll be specific only about numbers I can stand behind (those are PandaStack's) and qualitative about everyone else. Where a use case has its own deep dive, I link it inline.
1. Running untrusted and AI-agent-generated code
This is the flagship use case, and the one driving most new microVM adoption in 2026. When an LLM writes code and you execute it, you are running untrusted code by definition — the model is a probabilistic text generator, not an authority you can trust with your host. A clever prompt injection turns "summarize this CSV" into "read every environment variable and POST it somewhere," and the model will happily emit `rm -rf /` if the conversation drifts there. Running that in your own process, a subprocess, or even a shared-kernel container is the infrastructure equivalent of leaving the gun loaded on the kitchen table.
Here's why a microVM fits where a container doesn't:
- A microVM fits because the blast radius of a malicious or buggy script is one disposable guest — its own kernel, memory, filesystem, and network namespace — so the worst case is a wrecked throwaway VM, not a compromised host.
- A container would share the one host kernel with every other workload, so a single kernel-level escape (a real, recurring class of CVE) turns one bad script into a host compromise — which is why a hardened container is a weaker boundary for arbitrary agent output (/blog/why-docker-is-not-a-sandbox).
- A microVM fits because you can throw it away after every run, cheaply, so the same code never sees two users' data — the isolation boundary is the VM, and disposability is what keeps it honest.
- A container would tempt you to reuse one long-lived environment across runs to amortize startup, quietly mixing trust domains in the same kernel.
The historical objection was speed: VMs booted in seconds, so per-request VMs were impractical and everyone reached for containers anyway. MicroVMs killed that objection. On PandaStack every create restores a baked Firecracker snapshot — kernel already booted, guest agent running, network stack open — at 179ms p50 (roughly 203ms p99), with no warm pool of idle VMs sitting around. The only slow path is the first-ever spawn of a brand-new template, which cold-boots in about 3 seconds and bakes the snapshot; every create after rides the fast restore path. The full mechanics are in /docs/internals/snapshot-restore, and the threat-model layering on top of the VM boundary is in /blog/secure-code-execution-for-ai-agents.
2. Serverless and Functions-as-a-Service
Firecracker exists because AWS built it for exactly this. Lambda runs every function invocation inside its own microVM, and Fargate uses the same substrate — this is the single largest deployment of microVMs on the planet, and it's the original use case. FaaS has a brutal set of simultaneous requirements: hard multi-tenant isolation (Lambda runs millions of customers' functions on shared fleets), per-invocation startup measured in milliseconds, and density high enough that the unit economics work. A classic VM is too heavy and slow to start; a container is too leaky to safely pack untrusted tenant code at that density.
A microVM fits because it threads that needle — a guest kernel per function for isolation, a minimal VMM (Firecracker boots with a tiny device model and a few MB of memory overhead) for density, and snapshot-restore for cold-start. PandaStack ships serverless functions on the same Firecracker substrate as everything else: each invocation runs in its own microVM with no warm pool, so an idle function costs nothing and a cold invocation is the same fast restore path as any other create. The honest trade is that a per-invocation VM has more overhead than re-running a warm container — you're buying isolation, and for untrusted or multi-tenant functions that's exactly the bill you want to pay.
3. Ephemeral CI/CD runners
CI is where "fresh and disposable" stops being a nice-to-have and becomes a security requirement. A CI job runs whatever's in the pull request — including PRs from forks you've never seen, which is to say, untrusted code with your secrets in the environment. The classic shared, long-lived runner is a horror show waiting to happen: one job poisons a cached dependency or drops a binary in a shared path, and the next job inherits it. The fix everyone reaches for is ephemerality — a clean environment per job, destroyed after — and microVMs make that affordable.
- A microVM fits because each job gets a pristine, hardware-isolated environment that's destroyed on completion, so cross-job contamination and cache-poisoning between builds simply can't happen.
- A container would share a kernel across jobs running on the same host, so a malicious or compromised build step has a real path to escape and reach other jobs or the runner host itself.
- A microVM fits because snapshot-restore makes a fresh-per-job VM start in well under a second, so the security win doesn't cost you minutes of boot time on every build.
- A container would force the usual ugly trade: reuse runners for speed and accept contamination risk, or recreate them for safety and eat the latency.
The pattern generalizes beyond CI to any "run this once, isolated, then vaporize it" job — webhook handlers, scheduled tasks, batch workers processing untrusted payloads. The dedicated walkthrough for the CI shape, with a runner-per-job design, is in /blog/ephemeral-ci-runners.
4. Per-tenant database isolation
Multi-tenant SaaS has a perennial argument about database isolation: one big shared database with a `tenant_id` column on every row (cheap, but one missing `WHERE` clause leaks every customer's data), versus a database per customer (strong isolation, but historically expensive to operate at scale). MicroVMs tilt that math. If spinning up an isolated database is cheap and fast, a database-per-tenant stops being a luxury and becomes a default you can actually afford.
A microVM fits because each tenant's database runs as its own Firecracker guest with its own kernel and a durable volume, so there's no shared query engine where a logic bug crosses the tenant boundary, and no noisy-neighbor tenant saturating a shared instance. On PandaStack a managed PostgreSQL 16 database is exactly this — a dedicated microVM per database, on the same substrate as your sandboxes and apps, with the data on a persistent volume rather than the ephemeral copy-on-write rootfs. The conceptual model lives in /blog/multi-tenant-code-execution; the database mechanics are in /docs/concepts/databases. A plain container per tenant would still share the host kernel — fine for soft multi-tenancy among trusted internal services, weak when tenants are mutually distrusting customers and the data is the whole product.
5. Remote browser isolation and headless browser sandboxes
Browsers are an enormous, perpetually-exploited attack surface, and increasingly you want to drive one programmatically — for AI agents that browse the web, scrapers, automated testing, or remote browser isolation (rendering risky pages away from the user's real machine). The threat is symmetric: a malicious site can try to break out of the browser and into the host, and your automation may be visiting genuinely hostile pages on purpose. You want the browser in a box you can destroy.
A microVM fits because the whole browser — renderer, JS engine, the lot — runs behind a hardware boundary with its own kernel, so a browser-zero-day or a drive-by exploit is contained to a disposable guest you tear down after the session. A container would put a browser sandbox escape one kernel-bug away from the host, and browser sandbox escapes are not rare. PandaStack ships a browser template (a headless browser stack baked into the snapshot) for exactly this — give an agent a real browser in its own microVM, let it click around hostile pages, and throw the VM away. Pair it with per-sandbox egress controls if exfiltration is in your threat model.
6. Code interpreters and data-analysis sandboxes
A code interpreter — ChatGPT's Advanced Data Analysis, or any "run this Python and show me the chart" feature — is the untrusted-code use case with a specific shape: stateful sessions, a heavy scientific Python stack, and artifacts (plots, CSVs) to read back out. It deserves its own entry because the requirements are distinctive: you want a warm environment with pandas and matplotlib already importable, you want to persist state across cells within a trusted session, and you want a clean teardown between users.
A microVM fits because each session is its own isolated guest with the data-science stack baked into the snapshot (zero per-run `pip install`), so model-generated analysis code runs against real libraries with hardware isolation and reads its outputs back through a filesystem API. A container would, again, share the kernel — acceptable for a single trusted notebook, dangerous the moment you run two users' analysis code on the same host. Below is the minimal loop with the PandaStack SDK: create a sandbox on the code-interpreter template, write the model's code to a file, run it with a timeout, and pull the artifact back as bytes. The full build is in /blog/code-interpreter-how-to.
from pandastack import Sandbox
# Model-generated analysis code we don't trust enough to run in-process.
user_code = '''
import pandas as pd
import matplotlib
matplotlib.use("Agg") # headless: no display in the guest
import matplotlib.pyplot as plt
df = pd.DataFrame({"city": ["NYC", "SF", "LA"], "pop_m": [8.3, 0.87, 3.9]})
df.sort_values("pop_m").plot.bar(x="city", y="pop_m", legend=False)
plt.savefig("/workspace/chart.png", dpi=120, bbox_inches="tight")
print("rows:", len(df))
'''
# A fresh, disposable microVM for this one untrusted run.
with Sandbox.create(template="code-interpreter", ttl_seconds=300) as sbx:
sbx.filesystem.write("/workspace/cell.py", user_code)
result = sbx.exec("python3 /workspace/cell.py", timeout_seconds=30)
assert result.exit_code == 0, result.stderr
# Read the generated chart back out as raw bytes.
png = sbx.filesystem.read("/workspace/chart.png")
with open("chart.png", "wb") as f:
f.write(png)
print(f"pulled {len(png)} bytes")
# the VM is destroyed here — no state survives to the next user7. Multi-tenant platforms on shared hardware
Step back from the specific cases above and there's a meta-use-case that ties them together: any platform that runs many customers' workloads on shared hardware and needs them not to be able to touch each other. That's Lambda, but it's also every PaaS, every notebook-hosting service, every "deploy your code to our cloud" product. The economic pressure is to pack tenants densely on the same machines; the security pressure is that those tenants are mutually distrusting strangers. Containers give you density but a shared kernel; classic VMs give you isolation but poor density and slow starts.
A microVM fits because it's specifically engineered for that pack-strangers-densely-and-safely problem — strong per-tenant isolation from a guest-kernel-per-workload, plus density and fast starts from a minimal VMM and snapshot-restore. It's the reason the entire serverless industry standardized on Firecracker rather than containers for untrusted multi-tenant execution. PandaStack is itself multi-tenant by design — orgs and members up top, and underneath, every tenant's sandboxes, databases, and apps are separate Firecracker guests with per-sandbox networking (its own Linux netns, veth pair, and tap, drawn from 16,384 pre-allocated /30 subnets per agent). The deeper treatment of running mutually-distrusting code on shared infrastructure is in /blog/multi-tenant-code-execution.
8. Reproducible build environments
Reproducible builds need a hermetic, pinned, identical-every-time environment — the build that runs on a developer's laptop should be byte-for-byte the one that runs in CI and the one that ships. Containers get you most of the way (a pinned image is a long step toward reproducibility), but they share the host kernel, so kernel-version differences leak into builds, and a build step that needs specific kernel behavior, mount semantics, or device access can behave differently across hosts. For builds that must be truly hermetic — or that compile untrusted third-party source as part of the job — the kernel itself becomes part of the contract.
- A microVM fits because the guest kernel is pinned alongside userspace, so the build sees the same kernel everywhere and host-kernel drift can't perturb the result.
- A container would share whatever kernel the host happens to run, leaving a class of subtle, host-dependent build differences that are miserable to debug.
- A microVM fits because snapshot-restore lets you bake a fully-provisioned build environment once and restore an identical copy per build in well under a second — fast hermeticity rather than a multi-second cold boot per job.
- A microVM fits because untrusted build steps (a malicious `postinstall` script, a compromised dependency) are contained behind the hardware boundary instead of running against your host kernel with your credentials in scope.
Copy-on-write makes this cheaper than it sounds: bake the toolchain and dependencies into a snapshot, then restore (or fork) per build so the heavy setup runs once and is shared copy-on-write across builds. The CoW rootfs mechanics are in /blog/copy-on-write-rootfs.
9. Per-user dev environments and cloud IDEs
Cloud development environments and remote IDEs — a full dev box per user, in the cloud, that you can attach a browser-based editor to — are a natural microVM fit, and a growing one. Each developer needs a real environment: install whatever they want, run a real kernel, get root inside their own box, keep state across sessions. You absolutely do not want one developer's runaway process, kernel module experiment, or `sudo` mishap affecting anyone else's environment on the same host.
A microVM fits because each developer gets what feels like a dedicated machine — their own kernel, root in their own guest, full freedom inside the box — while the platform safely packs many of them per host, and snapshots make "pause my environment overnight and resume it instantly tomorrow" cheap. A container would give a more constrained, shared-kernel environment where giving every developer real root is a non-starter, and one user's kernel-level mischief is everyone's problem. This shape overlaps with git-driven app hosting — connect a repo and get a running, isolated environment behind a stable URL — which on PandaStack runs on the same substrate with blue-green deploys and scale-to-zero when idle. The honest caveat for dev environments: persistence matters as much as isolation here, so you want durable volumes (or snapshot-on-idle) so a paused environment doesn't lose state, not just an ephemeral rootfs.
When a microVM is the wrong tool
An honest catalog has to include the cases where you shouldn't reach for a microVM. The boundary isn't free — there's a real, if small, overhead per guest, and a platform layer to operate if you self-host.
- Code you wrote and fully trust: if it isn't user- or model-generated, a plain process or a container is simpler, faster, and entirely sufficient. Don't summon a hypervisor to run code you'd happily run on your laptop.
- Ultra-high-density, ultra-short, trusted functions where even a few MB and a few ms of per-guest overhead dominate, and there's no untrusted input — a warm container pool may win on raw throughput.
- Workloads that need true bare-metal device access or GPU passthrough that your VMM doesn't cleanly support — check the capability before assuming the VM boundary is transparent.
- When something lighter genuinely suffices: for sandboxing pure, deterministic computation with no syscalls, a WebAssembly sandbox can be lighter still — the trade-offs are in /blog/wasm-vs-microvm.
The bottom line
Across all nine cases the common thread is the same trade: you need hardware-grade isolation for code or tenants you don't fully trust, and you need it without the boot tax and density penalty that made classic VMs impractical per-request. That's the exact gap microVMs were built to close, which is why they quietly run Lambda, Fargate, agent code interpreters, CI fleets, and a growing share of multi-tenant platforms. If your workload is on this list — untrusted AI code, serverless, ephemeral CI, per-tenant databases, browser isolation, data-analysis sandboxes, multi-tenant execution, hermetic builds, or cloud dev boxes — a Firecracker microVM is very likely the right primitive, and the question is only whether you build on it directly or adopt a platform. PandaStack's bet is the latter: an open-source, Apache-2.0 Firecracker platform where every sandbox, database, and app is its own microVM, snapshot-restored on every create (179ms p50) with copy-on-write forking (~400ms same-host), that you can run end-to-end on your own KVM hosts. If one of these use cases is yours, the roundup of how to choose a platform is in /blog/best-code-execution-sandboxes.
Frequently asked questions
What are microVMs used for?
The core use cases all share one shape: running code or tenants you don't fully trust, with hardware-grade isolation, without a multi-second boot. In practice that means running untrusted or AI-agent-generated code, serverless/FaaS (AWS Lambda runs every invocation in a Firecracker microVM), ephemeral CI/CD runners, per-tenant database isolation, remote browser isolation and headless browser sandboxes, code interpreters and data-analysis tools, multi-tenant platforms packing many customers on shared hardware, reproducible/hermetic build environments, and per-user cloud dev environments. In each, a microVM gives every workload its own guest kernel behind a KVM boundary, so an escape or a runaway process is contained to a disposable VM rather than your host.
What is Firecracker used for?
Firecracker is a minimal open-source VMM (written in Rust) built by AWS to run microVMs at scale. Its largest use is AWS Lambda and Fargate, which run customer workloads in Firecracker microVMs for strong multi-tenant isolation with millisecond-class startup. Beyond AWS, Firecracker underpins many code-execution sandboxes for AI agents, ephemeral CI runners, browser isolation, and multi-tenant platforms — anywhere you need to run untrusted code densely and safely. It's deliberately spartan (a tiny device model, low memory overhead, fast boot), which is exactly what makes it suited to per-request and per-tenant isolation that classic VMs were too heavy for.
When should I use a microVM instead of a container?
Use a microVM when you're running code or tenants you don't fully trust and a kernel escape would be unacceptable — untrusted/AI-generated code, CI jobs from forked PRs, mutually-distrusting SaaS tenants, or anything where one workload must not be able to reach another. Containers share the host kernel, so a kernel-level escape compromises the host; a microVM gives each workload its own guest kernel behind a hardware (KVM) boundary, so the blast radius is one disposable VM. Stick with a container when the code is yours and trusted, or when ultra-high density of short, trusted functions matters more than isolation — there's no point paying for a hypervisor to run code you wrote and trust.
Does AWS Lambda use microVMs?
Yes. AWS built Firecracker specifically for Lambda and Fargate, and every Lambda invocation runs inside its own Firecracker microVM. This is the largest microVM deployment in existence and the original motivating use case: Lambda runs millions of customers' functions on shared fleets, which demands hard per-tenant isolation, millisecond-class startup, and high density all at once — the exact combination microVMs were designed to deliver, and that containers (shared kernel) and classic VMs (slow, heavy) each fail at.
Are microVMs only for AI code execution?
No — running untrusted AI-agent code is the fastest-growing use case in 2026, but it's one of many. MicroVMs also power serverless platforms (Lambda/Fargate), ephemeral CI/CD runners, per-tenant database isolation, remote browser isolation, code interpreters, multi-tenant compute platforms, reproducible build environments, and per-user cloud dev environments. The common requirement across all of them is hardware-grade isolation for untrusted code or mutually-distrusting tenants, combined with fast startup and good density. AI code execution is simply the case where that requirement has become most visible most recently.
49ms p50 cold start. Fork, snapshot, and scale to zero.