# How to snapshot a sandbox and start new ones from it Call `sbx.snapshot({ name, retentionDays })`. Then call `sandboxes.create({ snapshot: id })` to start a new sandbox from that machine. **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](/docs/pricing#snapshots-images-and-volumes)). Set up a machine once. Every later task then skips the clone, the install and the build. ## Prepare once, start many ```ts check import { 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); } ``` ```python check from withruntime import Runtime runtime = 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) ``` ```bash no-run snap=$(runtime sandboxes snapshot "${id}" --name flask-ready --retention 30) runtime sandboxes create --snapshot "${snap}" runtime snapshots ls ``` A 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](/docs/storage#snapshots-survive-their-server)). 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](/docs/storage#snapshots-survive-their-server)). ## 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](/how-to/pause-and-resume-a-sandbox)** 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](/how-to/fork-a-running-sandbox)** when you want running copies now. A fork takes its own snapshot and deletes it when it ends, so it is free. - **[An image](/how-to/build-an-image-from-a-recipe)** 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 `retentionDays` value that fits the job. Delete a snapshot you have replaced with `runtime.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](/how-to/attach-a-volume)). - **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](/docs/security#secrets-sandboxes-never-see). A copy then holds only the placeholder, never the key. Snapshots suit [agent evals and SWE-bench](/use-cases/agent-evals-and-swe-bench) and [RL environments](/use-cases/rl-environments), where every episode should start from the same known state. The concept is explained in [what is a sandbox snapshot?](/glossary/sandbox-snapshot). Facts on this page were checked on 26 October 2026.