# MicroVM vs container: which isolates untrusted code better? A container shares the host's kernel; a microVM runs its own kernel behind hardware virtualization, so a kernel exploit stays inside it. **Runtime gives every sandbox a microVM and still starts it in about a third of a second.** Each Runtime sandbox is a Firecracker microVM with its own Linux kernel, and a new one ran its first Python command 351 ms after the create request at the median, measured over the public internet on 24 September 2026 ([speed](/docs/speed)). Containers still run inside it, with Docker. ## How a container isolates code A container is, in Docker's words, "simply an isolated process with all of the files it needs to run." The host kernel draws the fence: - **Namespaces** give the process its own view of processes, network and mounts. Docker calls them "the first and most straightforward form of isolation." - **Control groups** cap CPU, memory and I/O. - **Capabilities** start containers "with a restricted set", and Docker's default seccomp profile "disables around 44 system calls out of 300+." - **AppArmor or SELinux** can confine it further. Every container on a machine uses the same kernel. Docker lists that as the benefit: containers "all share the same kernel, allowing you to run more applications on less infrastructure." It is also the risk for untrusted code: the program talks to the host kernel directly, through every system call the seccomp profile allows, and a bug in any of them is a bug in the one kernel every tenant shares. ## How a microVM isolates code A microVM is a small virtual machine. The monitor, Firecracker for example, uses KVM to create a machine and boots a guest Linux kernel inside it. The code talks only to that guest kernel. To reach the host it has to get through the virtualization boundary and a device model that Firecracker's site counts at "only 5 emulated devices", and then past a monitor confined by seccomp and a jailer. ## Side by side | | Container (Docker, default runtime) | MicroVM (Firecracker) | | ---------------------- | ----------------------------------------------------------------- | ------------------------------------------------------------------ | | Isolation boundary | Namespaces, cgroups, capabilities, seccomp on the host kernel | Hardware virtualization through KVM | | Kernel | The host's, shared by every container | Its own guest kernel per microVM | | Attack surface to host | The host kernel's system calls, minus about 44 blocked by default | 5 emulated devices, in the project's count, and a filtered monitor | | Start time | Docker publishes no figure | Up to 125 ms to guest init, in the project's specification | | Memory overhead | Docker publishes no figure | Up to 5 MiB for the VMM on a 1 vCPU, 128 MiB guest | | Compatibility | Any Linux program, on the host's kernel version | Any Linux program, on the guest's own kernel | | Root inside | Mapped to host root unless user namespaces are enabled | Root of the guest only | | Who uses it | Docker; Daytona's default sandboxes | AWS Lambda and Fargate; E2B, Vercel Sandbox, Runtime | Firecracker's figures come from its specification, measured on AWS metal hosts with a minimal guest; they cover the monitor, not a full sandbox. Docker's user namespace remapping is off unless enabled on the daemon. ## Is a container enough for AI-generated code? For code you wrote and trust, containers are the standard and work well. For code a model wrote, or a user pasted, the question is what happens when it finds a kernel bug. In a container, it is on the host's kernel with every other tenant. In a microVM, it has reached a guest kernel on a throwaway machine. A third option, gVisor, sits between the two: an application kernel in user space that intercepts a container's system calls. See [gVisor vs Docker](/compare/gvisor-vs-docker) and [Firecracker vs gVisor](/compare/firecracker-vs-gvisor). ## When each fits - **Pick containers** for your own services and CI on your own machines, where every workload is trusted and density matters most. - **Pick a microVM** for untrusted, multi-tenant or model-written code: agent sandboxes, code interpreters, grading, evaluations and per-user environments. - **Use both** when the untrusted code itself needs containers: run Docker inside the microVM. ## Why Runtime chose a microVM per sandbox - **One kernel per sandbox.** Every sandbox is a Firecracker microVM with its own Linux kernel and disk, on dedicated servers Runtime operates. - **Root inside is harmless outside.** `sudo` works in the sandbox, and root still cannot change network rules, CPU, memory or cost, which the host enforces ([security](/docs/security)). - **Containers inside when you need them.** `sudo enable-docker` installs Docker Engine, Buildx and Compose in the sandbox ([Docker](/docs/sandbox-environment#docker)). - **The whole machine pauses.** A paused sandbox keeps its files, memory and running processes, and a fork copies a running sandbox. ```ts check import { Sandbox } from "withruntime"; await using sbx = await Sandbox.create({ diskMiB: 8192 }); await sbx.exec("sudo enable-docker", { check: true, timeoutMs: 300_000 }); const run = await sbx.exec("docker run --rm hello-world", { timeoutMs: 300_000 }); console.log(run.stdout); ``` ```python check from withruntime import Sandbox with Sandbox.create(disk_mib=8192) as sbx: sbx.exec("sudo enable-docker", check=True, timeout_ms=300_000) run = sbx.exec("docker run --rm hello-world", timeout_ms=300_000) print(run.stdout) ``` The container runs inside the sandbox's own kernel, so a container escape reaches only that microVM. New accounts get 50 free sandbox hours, no card. More: [what is a microVM?](/glossary/microvm), [run Docker in a sandbox](/how-to/run-docker-in-a-sandbox), [run untrusted LLM code](/use-cases/run-untrusted-llm-code). ## Sources Checked 25 September 2026. - [Docker: what is a container?](https://docs.docker.com/get-started/docker-concepts/the-basics/what-is-a-container/), [Docker Engine security](https://docs.docker.com/engine/security/), [seccomp profiles](https://docs.docker.com/engine/security/seccomp/), [user namespaces](https://docs.docker.com/engine/security/userns-remap/) - [Firecracker](https://firecracker-microvm.github.io/), [README](https://github.com/firecracker-microvm/firecracker), [specification](https://github.com/firecracker-microvm/firecracker/blob/main/SPECIFICATION.md) - Provider isolation from Runtime's comparisons, checked 23 September 2026: [E2B](/docs/e2b-alternative), [Vercel Sandbox](/docs/vercel-sandbox-alternative), [Daytona](/docs/daytona-alternative) Facts on this page were checked on 25 September 2026.