On Runtime, a snapshot keeps the whole machine by default, including memory and running processes. Its encrypted off-server copy is included at no extra charge. backedUp: true confirms that the copy was checked. A snapshot costs $0.08 per decimal GB per 30-day month. You pay only for the bytes that this snapshot alone stores. Blocks that two of your snapshots share are counted once. The rate applies from 23 September 2026 (pricing). Set up a machine once. Every later task then skips the clone, the install and the build.
Prepare once, start many
TypeScriptimport { Runtime, Sandbox } from "withruntime";const runtime = new Runtime();const base = await Sandbox.create();await base.exec("git clone --depth 1 https://github.com/pallets/flask /workspace/flask", { timeoutMs: 120_000,});await base.exec("pip install --quiet -e /workspace/flask", { timeoutMs: 300_000 });const snapshot = await base.snapshot({ name: "flask-ready", retentionDays: 30 });await base.stop();// Any time in the next 30 days, from any process:for (const task of ["fix-1", "fix-2", "fix-3"]) { await using sbx = await runtime.sandboxes.create({ snapshot: snapshot.id, labels: { task }, }); console.log(task, (await sbx.exec("python3 -c 'import flask; print(flask.__name__)'")).stdout);}Pythonfrom withruntime import Runtimeruntime = Runtime()base = runtime.sandboxes.create()base.exec("git clone --depth 1 https://github.com/pallets/flask /workspace/flask", timeout_ms=120_000)base.exec("pip install --quiet -e /workspace/flask", timeout_ms=300_000)snapshot = base.snapshot(name="flask-ready", retention_days=30)base.stop()for task in ["fix-1", "fix-2", "fix-3"]: with runtime.sandboxes.create(snapshot=snapshot["id"], labels={"task": task}) as sbx: print(task, sbx.exec("python3 -c 'import flask; print(flask.__name__)'").stdout)Terminalsnap=$(runtime sandboxes snapshot "${id}" --name flask-ready --retention 30)runtime sandboxes create --snapshot "${snap}"runtime snapshots lsA sandbox started from a memory snapshot takes the snapshot's size: its
vCPUs, memory and disk. It continues that machine. A sandbox started from a
disk snapshot boots fresh, so you can set any size. Pass vcpu, memoryMiB
or diskMiB. The disk must be at least as large as the saved one. Either way,
the result is a new sandbox with its own id, billed like any other.
What taking one does
- A running source pauses while the snapshot captures it, then resumes. The more memory it holds, the longer this takes.
- A paused source stays paused. Snapshot a paused sandbox to keep it as a template while it waits.
- The snapshot lives on its source's server, where sandboxes started from it run. Its checked copy off that server lets it survive the loss of that server.
Durability, state by state
durability.state |
Meaning |
|---|---|
pending |
Being copied off the server |
durable |
Copied, read back and checked; backedUp is true |
restoring |
Its server was lost. It is being restored to another server from its copy |
failed |
It could not be copied; error says why |
none |
A temporary fork snapshot, or a capture waiting for compression before copy |
A captured memory snapshot can be ready with compressionPending: true. In
that state, you can start copies before compression finishes. The charge uses
its final compressed size. The off-server copy waits for that final form, so
backedUp is false while compression is pending
(snapshot storage).
While a snapshot is restoring, a create or fork from it returns 503
snapshot_restoring. Try again in a few minutes. The snapshot returns to a
server in its region (storage).
Options and limits
| Setting | Default | Range or rule |
|---|---|---|
mode |
"memory" |
"memory" keeps the machine; "disk" saves the root filesystem for a fresh boot |
retentionDays |
none | Kept while you have credit (7 days without credit), or for 1 to 365 days. To delete it sooner, use snapshots.delete |
name, labels |
none | Your own names and labels for finding it later |
| Source with volumes | — | Refused: a sandbox with volumes cannot be snapshotted |
snapshot on create |
— | Not together with image |
| Storage without credit | — | Snapshots count toward the 10 GB of saved copies included each month |
| MCP | — | runtime_snapshots with create, list, get, update, delete |
Pass mode: "disk" in JavaScript or mode="disk" in Python to save only the
root filesystem. Copies boot fresh without the source's running processes.
Both modes pause a running source until capture finishes, then resume it.
Snapshot, pause or fork?
- Pause when you want the same sandbox back. Each pause replaces the previous saved state.
- Snapshot when you want new sandboxes from one moment, today and next week, as many as you like.
- Fork when you want running copies now. A fork takes its own snapshot and deletes it when it ends, so it is free.
- An image when files are enough and nothing in memory matters.
Mistakes to avoid
- Keeping snapshots forever by accident. Each one is charged for as long as
it is kept. Pick a
retentionDaysvalue that fits the job. Delete a snapshot you have replaced withruntime.snapshots.delete(snapshot.id). - Snapshotting a sandbox with volumes. The request is refused. Keep the volume's data on the volume. Snapshot a sandbox without it, and attach the volume to each copy (volumes).
- Snapshotting mid-write. A running source pauses for a moment and keeps its memory. A process that is part-way through its work continues in each copy. For a clean starting point, let setup finish first.
- Secrets in the snapshot. Every copy holds whatever the source kept in its files and memory. Pass API keys to code as secrets sandboxes never see. A copy then holds only the placeholder, never the key.
Snapshots suit agent evals and SWE-bench and RL environments, where every episode should start from the same known state. The concept is explained in what is a sandbox snapshot?.
Facts on this page were checked on 26 October 2026.