MicroVMs give AI-generated code a separate guest kernel; ordinary Linux containers share their container host's kernel. Containers can suit reviewed code with restricted permissions. For arbitrary code from users or agents, a microVM adds a hardware virtualization boundary. Vercel Sandbox is one managed implementation of that approach.
The decision depends on what your application lets the generated program do. Having a model propose a patch for review creates different risks from letting an agent immediately execute a shell command, even if both use the same model.
Copy link to headingWhat changes at the kernel boundary?
Containers group processes with their application files and dependencies. Linux namespaces give those processes separate views of resources, such as process identifiers and network interfaces. Control groups account for and limit resource use. These container isolation mechanisms rely on the container host's kernel.
That machine can itself be a VM. If several ordinary containers run inside one VM, they still share that VM's kernel. Moving a container to a cloud instance doesn't, by itself, give each container a separate kernel.
MicroVMs are small virtual machines with their own guest kernels and reduced virtual hardware configurations. In a KVM-backed implementation such as Firecracker, a virtual machine monitor works with Linux's virtualization support to run the guest. Application system calls reach the guest kernel, and the virtualization boundary separates that guest from the host.
Vulnerabilities in a shared kernel can undermine the boundary between containers that depend on it. In a microVM, gaining control of the guest kernel still leaves the boundary to the host to cross.
The virtualization stack and exposed host interfaces can also contain vulnerabilities. Having a dedicated kernel doesn't make an environment escape-proof.
The container column describes a conventional shared-kernel runtime. Sandboxed runtimes such as gVisor add an application kernel, so a container image alone doesn't tell you which boundary protects its execution.
Copy link to headingWhy does generated code need a different review?
An application that runs a fixed, reviewed transformation can restrict inputs to a defined format. An application that asks a model to write the transformation gives the resulting program much more freedom. The program may open files, install dependencies, or make network requests that the original feature never required.
Consider a support product that generates JavaScript to analyze an uploaded export. The intended operation is grouping records by issue type. Executing that script inside the API process would give it the API process's permissions, potentially including database access. Separating execution lets the controller provide the selected export without handing over the backend's credentials.
The code's origin is only part of the decision. Coding agents can execute instructions influenced by a repository file or package installation script. Even if the agent itself is software you trust, the code it runs can cross a different trust boundary. Evaluate the executed workload and its inputs together.
An AI sandbox supplies the restricted execution environment. Choosing containers or microVMs determines part of how that restriction is enforced; the controller still decides what enters the environment.
Copy link to headingWhen can a hardened container be enough?
Conventional containers can fit workloads whose code and dependencies your team controls, with a shared-kernel risk your organization accepts. For example, a model may draft a data transformation that goes through code review and your deployment process before it ever runs. That workload can follow the same container security practices as other reviewed application code.
For container execution, remove unnecessary privileges and expose only the files the job needs. The seccomp profile restricts available system calls, while resource limits constrain consumption. Review host mounts and daemon access carefully. Giving a program control of the host's Docker daemon can let it request privileges far beyond those of its original container.
Rootless Docker runs the daemon and containers without host root privileges. It reduces the consequences of some daemon and runtime vulnerabilities while preserving the shared-kernel architecture.
When users submit arbitrary programs or agents change tools without review, the code's behavior becomes harder to predict. Evaluate an additional isolation boundary for these workloads while keeping container images for packaging.
Copy link to headingWhen does a microVM fit better?
MicroVMs are a strong candidate for separating mutually untrusted executions that need a Linux environment. Examples include hosted coding agents running unfamiliar repositories and products executing scripts from different customers. Sharing one microVM gives those jobs a shared guest kernel.
The separate guest kernel is also useful when the workload needs privileges inside its environment. For example, a coding agent may need to start Docker and run application tests against a database container. Placing that daemon inside the agent's microVM keeps its administrative scope within the guest. Vercel's guide to running Docker in Sandbox describes this deployment option.
The microVM separates the workspace from its host while containers isolate the test services inside the guest. Escaping one container can expose other services and files in that guest's workspace. Place services in separate microVMs when your design requires a kernel boundary between them.
Notion Workers uses Vercel Sandbox to execute code authored by developers and agents. Its architecture combines per-worker microVMs with network policies and credential injection outside the execution environment. Those controls address different risks; the guest kernel alone cannot restrict which authorized API operations a worker performs.
Copy link to headingDo you have to replace container images?
Container packaging can remain part of a microVM workflow. The image describes the environment's files and installed software. The runtime decides how that environment executes. Verify the image formats and startup behavior supported by the microVM implementation you choose.
For example, Vercel Sandbox can boot from an image in Vercel Container Registry. You can define a toolchain in a Dockerfile and use that image for sandbox execution. Running a Docker daemon inside the resulting sandbox is a separate choice for workloads that use Docker to build images or start containers.
Use a tested base image that contains dependencies but no user data. After a job runs, its filesystem may contain modified tools or customer records. Restoring that state for another customer would carry those files across the intended boundary, regardless of whether the environment uses containers or microVMs.
Copy link to headingHow do you run AI-generated code in Vercel Sandbox?
The controller should create the environment and set its policies before submitting generated code. The following server-side TypeScript function runs a JavaScript program in a disposable Vercel Sandbox. It returns the process exit code, which reports how execution ended without proving the result correct.
Install @vercel/sandbox in your Node.js project and configure Sandbox authentication. Call this function after your application authorizes the job. The program runs in the managed image's Node.js environment with outbound access disabled, so it cannot download packages.
import { Sandbox } from '@vercel/sandbox';
export async function runGeneratedCheck(source: string) { if (Buffer.byteLength(source, 'utf8') > 64_000) { throw new Error('Program exceeds the input limit'); }
const sandbox = await Sandbox.create({ image: 'vercel/sandbox/universal', persistent: false, networkPolicy: 'deny-all', timeout: 60_000, });
try { await sandbox.writeFiles([ { path: 'check.mjs', content: Buffer.from(source, 'utf8') }, ]);
const command = await sandbox.runCommand({ cmd: 'node', args: ['check.mjs'], detached: true, timeoutMs: 10_000, }); const result = await command.wait();
return { exitCode: result.exitCode }; } finally { await sandbox.stop(); }}The SDK applies a command deadline and a separate session timeout. The finally block attempts cleanup when execution completes or throws. In a production controller, record cleanup failures for recovery, enforce job quotas, and set the controller's own request deadline. If you add returned files or logs, bound their size and treat their contents as untrusted.
Vercel Sandbox persists files between sessions by default, so persistent: false makes this example disposable. The firewall defaults to allowing outbound access; deny-all blocks it before the program starts.
Copy link to headingWhat should you measure before choosing?
Measure the time from submitting a job to receiving a usable result. VM boot time or container process startup is only one part of that interval. Pulling an image, preparing dependencies, and transferring the input can dominate the user's wait.
Use the same workload and permission policy for both candidates. Test fresh environments separately from reused ones, and include realistic concurrency. Record execution failures as well as completion time; an environment that starts promptly but cannot run a required dependency hasn't met the workload's needs.
Lifecycle behavior can change these results without changing the isolation architecture. Vercel's snapshot implementation update changed how snapshots are created and restored. Test the service configuration you intend to deploy before applying results from another microVM implementation.
Copy link to headingWhat does neither approach protect automatically?
Code in either environment can misuse the access you intentionally grant. Generated programs with production API credentials can make unwanted requests without escaping anything. Limit data and credentials to the job, and enforce business authorization in the service that performs the operation.
An isolated program can also return misleading results or place sensitive input in its output. Disabling networking doesn't stop your controller from collecting that output and forwarding it elsewhere.
Choose the kernel boundary alongside application-level permissions and output controls, then test the full path with requests it should reject.
Copy link to headingFrequently asked questions
Copy link to headingDoes a container image define the isolation boundary?
No. Container images package application files and dependencies; the runtime determines how processes execute. An image may run with a conventional container runtime or with a service that boots it in a separate guest.
Copy link to headingCan containers run inside a microVM?
Yes, if the guest environment supports the required container runtime. The containers share that guest's kernel, while the microVM adds a boundary between the guest and its host. Use separate guests when workloads inside the VM must be isolated from each other at the kernel level.
Copy link to headingDoes rootless Docker provide the same isolation as a microVM?
No. Rootless Docker reduces host privileges through user namespaces, but containers still share the host kernel. MicroVMs add a guest kernel and virtualization boundary, with their own configuration and maintenance requirements.
Copy link to headingDoes all AI-generated code require a microVM?
No. Code that your team reviews and deploys through its normal process can use the controls appropriate to that application. Immediate execution of arbitrary generated code creates a different risk, especially across customers, and warrants evaluating microVMs or another additional isolation mechanism.