Skip to content
Runtime

How to fork a running sandbox into parallel copies

Call sbx.fork({ count }) to make up to 100 running copies. Each copy has the source's files, memory and processes. The call returns all copies at the same time.

On Runtime, a fork copies a live machine, not just its disk. A server that was running in the source is still running in every copy. The snapshot that the fork takes for itself is deleted when the fork ends, and it is never billed. Three waiting 2 vCPU, 4 GiB copies cost 3 × $0.03125, about $0.094 an hour, and nothing more (rates checked 25 October 2026, pricing). Copies start on the source's server while it has room. When that server is full, copies start on another server. The snapshot is copied there first.

Fork a machine with a server running

Start the work once, fork, and each copy carries on from that moment:

TypeScriptimport { Sandbox } from "withruntime";await using base = await Sandbox.create();await base.exec("pip install --quiet requests", { timeoutMs: 120_000 });await base.spawn("python3 -m http.server 8000", { cwd: "/workspace" });const copies = await base.fork({ count: 3, labels: { experiment: "retry-policy" } });for (const copy of copies) {  const probe = await copy.exec("curl -s -o /dev/null -w '%{http_code}' localhost:8000");  console.log(copy.id, probe.stdout); // 200: the server came along}await Promise.all(copies.map((copy) => copy.stop()));
Pythonfrom withruntime import Sandboxwith Sandbox.create() as base:    base.exec("pip install --quiet requests", timeout_ms=120_000)    base.spawn("python3 -m http.server 8000", cwd="/workspace")    copies = base.fork(count=3, labels={"experiment": "retry-policy"})    for copy in copies:        probe = copy.exec("curl -s -o /dev/null -w '%{http_code}' localhost:8000")        print(copy.id, probe.stdout)    for copy in copies:        copy.stop()
Terminalruntime sandboxes fork "${id}" --count 3runtime sandboxes fork "${id}" --count 3 --keep-snapshot

With count, fork returns a list. Without it, it returns one sandbox. The source pauses while the fork captures it. Then the source wakes and is running again when the call returns. It takes longer the more memory the source holds. A paused source stays paused.

Options

Option Default What it does
count one copy How many copies: 1 to 100 on prepaid credit, 1 to 4 without credit
funding the source's Accepted and ignored, as on create
name, labels none Handles for the copies
keepSnapshot false Keeps the fork's snapshot, so you can start more copies later. It is then billed as snapshot storage
MCP — runtime_sandboxes_fork

Each copy gets the source's vCPUs, memory, disk and CPU setting (reserved CPU, or a raised floor). It is billed as a create of that size would be.

When a copy fails

A fork that fails after its snapshot returns the error from the failing step. The copies that did start are listed in details.startedSandboxIds. They keep running, and billing, until you stop them.

TypeScriptimport { RuntimeError, Sandbox } from "withruntime";const base = await Sandbox.create();try {  const copies = await base.fork({ count: 5 });  console.log(copies.map((copy) => copy.id));} catch (error) {  if (!(error instanceof RuntimeError)) throw error;  const started = (error.details?.startedSandboxIds ?? []) as string[];  for (const id of started) await (await Sandbox.connect(id)).stop();  console.log(error.code, error.hint);}

A failed fork is over. Retrying with the same idempotency key returns the same error, so fork again with a new key (idempotency keys).

Limits and refusals

Case What happens
More copies than the plan allows invalid_request (400): 100 on prepaid credit, 4 without credit
Copies past four at the same time without credit no_credit_running_limit. More copies than that never fit without credit
Copies needing over a quarter of the free memory of each server in the region no_capacity (503), with how many fit now in details.fits. Fork fewer, or try again later
Source with reserved CPU or a floor above 250 Copies cannot fit the limits without credit, so the fork runs only once the account holds credit
fork_unavailable (503) Turned off there on purpose. Retrying does not help
Fork stopped partway, source left paused The source stays paused. A fork-left-paused notice says how to wake it

A paid account runs 100 sandboxes at the same time. A fork's copies count toward that limit. A fork that would go past the limit is refused before its source is paused (how many at the same time).

Where forking pays off

  • Trying several fixes. A coding agent reaches a failing test with the repo built and the dev server up. It then forks one copy per candidate fix (coding agent sandbox).
  • Sampling answers. Run the same prepared environment against several model outputs, and keep the best (RL environments).
  • Evaluation episodes. Every episode starts from exactly the same memory and process state (agent evals).

Mistakes to avoid

  • Forgetting the copies. Each copy is a sandbox that runs on its own, and it is billed until it stops or pauses. Stop each one when its attempt is done, even after an error.
  • Forking for later. Copies start now. To start copies next week, take a snapshot, or pass keepSnapshot: true.
  • Retrying a fork without credit that asks for too many. More copies than the four allowed at the same time without credit never fit, however long you wait. Ask for fewer. An account that holds prepaid credit is not held to the limit without credit.

The idea behind forks is explained in what is a sandbox fork?.

Facts on this page were checked on 26 October 2026.

Related.

100 free hoursin your first 30 days.

of a 1 GB machine

  • No credit card
  • Four sandboxes at once, 2 vCPU and 4 GiB each
  • Then prepaid credit from $10, no plan fee
Start free, no card
Start free, no card