Skip to main content
Comparison

Agent OS Exec vs Container VM

When to use a container VM versus Agent OS Exec for running untrusted code.

Agent OS Exec and container VMs both run untrusted code in isolation, but they sit at different points on the weight-versus-flexibility curve. Picking the right one depends on what you need to run.

Agent OS Exec boots a fully virtualized VM for each runtime and runs guest code inside the AgentOS sidecar. There is no Docker daemon, orchestrator, or vendor account: install @rivet-dev/agentos and call JavaScriptRuntime.create() or PythonRuntime.create(). It is built for lightweight, high-fanout code execution like AI tool calls, user scripts, and plugins, where you want granular permissions and a small footprint.

Container VMs (e2b, Daytona, Modal, Cloudflare Containers, and similar) spin up a full OS image with system packages, a writable disk, and the ability to run arbitrary binaries. They are built for heavyweight workloads that need a complete environment: coding agents, long-lived dev sessions, or anything that shells out to native tools.

How isolation works

The biggest difference is what the isolation boundary is made of.

  • Agent OS Exec runs guest code in a V8 isolate hosted by the AgentOS sidecar. Every JavaScriptRuntime.create() is a separate VM with its own virtual filesystem, process table, network policy, and resource accounting. The process-wide sidecar pool is shared by default. Guest code never calls real Node.js builtins, opens a real host socket, or touches the real disk. See Architecture.
  • Container VMs isolate with OS-level primitives (namespaces, cgroups, or a microVM). The guest runs a real kernel and a real filesystem, so it can do anything a Linux process can, constrained by the container’s configuration.

Agent OS Exec presents normal Linux semantics to the code it runs (a POSIX-like virtual filesystem, processes, pipes, PTYs, sockets) without granting access to the host that backs them.

Comparison

DimensionAgent OS ExecContainer VM
Isolation boundaryVirtualized VM + V8 isolate in a sidecar processOS container or microVM
Setupnpm install @rivet-dev/agentosVendor account or Docker host
HardwareRuns on your infrastructureOften vendor-hosted
FilesystemVirtual, in-memory, per runtimeFull OS filesystem
NetworkExplicit per-VM allow, deny, or rulesFull, or firewall rules
PermissionsPer-scope policy (fs, network, childProcess, process, env, tool)Coarse, container-level
LanguagesJavaScript, TypeScript, and PythonAny language the image supports
Arbitrary binariesNo (guest binaries run through the VM, not the host)Yes
Crash domainVM state is isolated; the default sidecar process is sharedOne container per VM

What Agent OS Exec gives you

These capabilities are the reason to reach for Agent OS Exec over a container when the workload fits in a Node-compatible runtime:

  • Explicit permissions. Every guest syscall is checked against a per-scope policy before any host resource is touched. The high-level client defaults to allow-all, so pass a restrictive policy for untrusted code. A denied operation fails with EACCES. See Permissions.
  • Virtual filesystem. Each runtime gets its own in-memory filesystem. Guest reads and writes never reach the host disk, and two runtimes writing the same path do not collide. See Filesystem.
  • Mediated networking. Guest fetch(), node:http, and raw sockets all flow through the kernel socket table, so you can allow, deny, or rule-match outbound traffic. See Networking.
  • Process-level isolation. Each runtime is its own VM, and each execute() or evaluate() call starts a fresh guest process so in-memory state does not leak between executions. See Architecture.
  • npm compatibility. Real npm packages run unmodified inside the VM, resolved over a faithfully mounted node_modules like a real filesystem. See Module Loading.

When to use each

Use Agent OS Exec when

  • You are running JavaScript, TypeScript, or Python (AI tool calls, user scripts, plugins, evaluation loops).
  • You want no vendor dependency and to run on your own infrastructure.
  • You need granular permissions over the filesystem, network, and child processes.
  • You are running many short tasks and want a small per-task footprint.

Use a container VM when

  • You need a full OS environment: system packages, arbitrary binaries, or languages beyond a Node-compatible runtime.
  • You need a persistent, long-lived environment such as a multi-hour dev session.
  • The workload genuinely needs a real kernel and a real disk.

Need a full isolated operating system?

If your workload needs complete VM environments (for example, running coding agents like Claude Code, Codex, or Amp), the VM Agent SDK provides a unified interface for driving agents inside VMs.

A minimal example

Booting an Agent OS Exec runtime takes no infrastructure beyond the installed package. The runtime owns its VM until you dispose it:

import { JavaScriptRuntime } from "@rivet-dev/agentos/javascript";

const runtime = await JavaScriptRuntime.create({
	permissions: {
		fs: "allow",
		network: "deny",
		childProcess: "allow",
		process: "allow",
		env: "allow",
	},
});

try {
	const result = await runtime.evaluate<{
		fileContents: string;
		networkBlocked: boolean;
	}>(`(async () => {
		const { writeFileSync, readFileSync } = await import("node:fs");
		writeFileSync("/workspace/note.txt", "inside the VM");
		let networkBlocked = false;
		try { await fetch("https://example.com"); } catch { networkBlocked = true; }
		return {
			fileContents: readFileSync("/workspace/note.txt", "utf8"),
			networkBlocked,
		};
	})()`);

	if (!result.success) throw new Error(result.error.message);
	console.log(result.value);
} finally {
	await runtime.dispose();
}

There is no container to build, no image to pull, and no daemon to keep running.

Performance

Agent OS Exec has no container image to pull or microVM to provision. Its cold start includes VM creation and the first language process; reusing a runtime keeps that VM, its filesystem, and its mounts alive while each execute() call starts a fresh guest process. See Benchmarks for the reproducible public-API benchmark and its measurement boundaries.