The short answer
Use Docker when the code is yours or your team's and runs on a machine you dedicate to it. Use Firecracker microVMs when the code is written by a model, for users you do not control, on hosts shared with other tenants. The difference is the kernel: containers share the host's, microVMs each get their own.
How each one isolates
Docker
A container is a set of Linux processes with their own namespaces (PID, mount, network, user), limited by cgroups. Docker's default seccomp profile blocks a few dozen dangerous syscalls and allows the rest. Everything else in the kernel, including file systems, the network stack and drivers, is shared with the host and every other container on it.
Firecracker
A microVM runs its own guest kernel on KVM. Code inside talks to the guest kernel, never to the host's. To reach the host, an attacker has to break KVM or the Firecracker process, which is written in Rust, emulates only virtio network, block and vsock devices plus a serial console, and runs under the jailer with seccomp filters, cgroups and an unprivileged user.
Side by side
| Docker (runc) | Firecracker microVM | |
|---|---|---|
| Kernel | Shared with the host | One guest kernel per sandbox |
| Escape surface | The host kernel's syscalls, the runtime | KVM and a small virtio device model |
| Cold start | Usually under a second with a cached image | About 125 ms to user space for a minimal guest |
| Start from a snapshot | Not built in (CRIU is experimental) | Built in: memory and device state restore |
| Memory overhead | A few MB per container | Under 5 MiB per VMM, plus the guest's own memory |
| Images | OCI images and Dockerfiles | A kernel and a root file system, often built from an OCI image |
| Host requirement | Any Linux host | /dev/kvm: bare metal or nested virtualization |
| GPU | Yes, with the NVIDIA Container Toolkit | No GPU passthrough |
| Tooling | Huge ecosystem | Low level: you build networking, images and orchestration |
The GPU row matters less than it looks. In an agent, the GPU work is the model, and it does not need to live next to the sandbox. Serve the model on GPUs, for example with gpuOS on your own cards, and keep the sandboxes on CPU hosts.
Startup and snapshots in practice
Agents create sandboxes all the time, so start time is part of the user experience. With Firecracker, the trick is to boot each template once, wait until its services are ready, and take a snapshot. A new sandbox restores that snapshot: Firecracker maps the memory file and loads pages as the guest touches them, so restore time does not grow with the template's memory size.
The same mechanism gives you pause and resume. Pausing writes the sandbox's memory and disk to a snapshot and frees the CPU and RAM. Resuming continues with processes, open files and the Python session exactly where they were. Docker can stop and start a container, but running processes do not survive that without CRIU.
Density and cost
Containers are denser: they share the page cache and the kernel, and an idle container costs almost nothing. A microVM reserves its guest memory, so RAM is the real limit on how many sandboxes fit on a host.
Two things close most of the gap for agents. CPU can be oversubscribed because agent sandboxes are idle most of the time, waiting for the model. And paused sandboxes free their RAM entirely, keeping only a snapshot on disk. On cpuos, a 2 vCPU / 4 GB sandbox costs $0.11 per running hour, and a paused one only pays snapshot storage.
Middle grounds
- gVisor (`runsc`): a drop-in Docker runtime with a user-space kernel. Stronger than plain runc, no KVM needed, slower on syscall-heavy work.
- Kata Containers: runs each container inside a lightweight VM (with QEMU, Cloud Hypervisor or Firecracker) behind the OCI interface, so Kubernetes and Docker workflows stay the same.
- A managed sandbox API: someone else runs the microVMs, networking, snapshots and cleanup. You call
create,execandpause.
Keep your Dockerfiles
Choosing microVMs does not mean giving up Docker as a build tool. cpuos turns an OCI image or a Dockerfile into a microVM root file system, boots it once and snapshots it as a custom template (Team plan and up). You keep building images the way you do today; the runtime underneath is a VM.
import { Sandbox } from "@cpuos/sdk"// "devbox" ships git, Python, Node, Go and Rust toolchainsconst sbx = await Sandbox.create({ template: "devbox", vcpu: 4, memory: "8GB" })await sbx.exec("git clone https://github.com/acme/api /work/api")const tests = await sbx.exec("cd /work/api && make test", { timeout: "10m" })cpuos is in early access. The SDK calls on this page show the API shape early-access teams build against; names can still change before general availability.