On Runtime, a paused sandbox stops billing for compute immediately. It costs $0.08 per GB of saved state a month. The same 2 vCPU, 4 GiB sandbox left running and idle costs $0.03125 an hour, or about $22.50 over 30 days. A paid sandbox stays paused while you have credit.
Pause and wake
TypeScriptimport { Sandbox } from "withruntime";const sbx = await Sandbox.create({ timeoutSeconds: 600 });await sbx.exec("echo state > /workspace/state.txt");await sbx.pause(); // memory and files are kept; compute billing stops// Later, even from another process:const again = await Sandbox.connect(sbx.id);await again.wake({ timeoutSeconds: 1200 });console.log((await again.exec("cat /workspace/state.txt")).stdout); // stateawait again.stop();Pythonfrom withruntime import Sandboxsbx = Sandbox.create(timeout_seconds=600)sbx.exec("echo state > /workspace/state.txt")sbx.pause() # memory and files are kept; compute billing stopsagain = Sandbox.connect(sbx.id)again.wake(timeout_seconds=1200)print(again.exec("cat /workspace/state.txt").stdout) # stateagain.stop()Terminalruntime sandboxes pause "${id}"runtime sandboxes wake "${id}"pause() returns once the sandbox's processors have stopped. Compute billing
ends at that point. The host then writes the memory to disk. A wake requested
in the meantime waits for that write. A woken sandbox runs while it works
again. A sandbox with a time limit gets a new limit of timeoutSeconds. Or it
keeps the limit it had when it paused, if that ends later.
What a pause keeps
| Kept | Detail |
|---|---|
| Files | The whole disk, as it was |
| Memory | Variables, caches, a loaded model, an open REPL |
| Running processes | A dev server or a watcher carries on after the wake |
| Its name | getOrCreate(name) finds it and wakes it |
| Where it wakes | On the same host. A wake never starts from a fresh boot |
Each pause replaces the previous saved state. A paused sandbox is one machine you come back to, not a history of copies. To start from the same copy again and again, take a snapshot instead.
Wake it by using it
A paused sandbox wakes by itself when a request needs it. That includes an
exec, a file, process, terminal, desktop or code-interpreter call, or a visit
to one of its shared ports. The call waits while the sandbox wakes. Then the call runs. A browser at a shared port sees
a short "Waking up" page that reloads itself.
So the cheapest way to keep a sandbox for an agent or a user is to let it pause when idle, and wake when used:
TypeScriptimport { Sandbox } from "withruntime";const dev = await Sandbox.getOrCreate("dev", { idlePauseSeconds: 900 });await dev.exec("git -C /workspace/app pull || true"); // wakes it if pausedawait dev.update({ idlePauseSeconds: 1800 }); // 0 turns it offPythonfrom withruntime import Sandboxdev = Sandbox.get_or_create("dev", idle_pause_seconds=900)dev.exec("git -C /workspace/app pull || true") # wakes it if pauseddev.update(idle_pause_seconds=1800) # 0 turns it offA sandbox also pauses itself after 300 seconds with nothing happening in it.
Nothing is happening when there is no request, no command or terminal running,
no open connection, no traffic and no CPU use. idlePauseSeconds sets that
wait, from 60 to 86,400 seconds. Set it to 0 to
never pause.
Options
| Setting | What it does |
|---|---|
sbx.pause(), sbx.wake() |
Pause now. Wake now, with an optional new timeoutSeconds |
onLeaseEnd: "pause" |
The default. At a time limit, or when credit runs out, the sandbox pauses |
idlePauseSeconds |
Pause after that many idle seconds (default 300; 60 to 86,400) |
autoWake: false |
A paused sandbox stays paused. Calls fail with sandbox_paused |
sbx.extend(seconds) |
Moves a time limit later, while it runs. No change without one |
POST /v1/sandboxes/{id}:retention |
How long a paid sandbox is kept paused: while you have credit, or 1 to 365 days |
runtime_sandboxes_manage |
The MCP tool. "action": "pause" or "wake" |
Python uses the same names in snake_case: on_lease_end,
idle_pause_seconds, auto_wake.
What it costs
| State | 2 vCPU, 4 GiB sandbox | Source |
|---|---|---|
| Busy | $0.08 an hour | Measured CPU plus reserved memory |
| Waiting | $0.03125 an hour | Memory plus the 50-millicore floor |
| Paused | $0.08 per decimal GB of saved state per 30-day month | Paused storage |
Paused storage counts the disk and memory-snapshot blocks that the sandbox alone owns. It leaves out shared base-image blocks. It also leaves out the size of the disk you asked for. Billing starts when the processors stop. It ends on a confirmed wake or deletion (paused storage).
- Paid sandboxes are kept as long as the account has credit, or for 1 to 365 days if you set that. When credit runs out, they are kept seven more days. A notice comes first.
- Sandboxes without credit are kept seven days for free. A paused one does not count toward the four running at the same time, or toward the month's free usage. Once the account holds credit, they are kept as paid ones are. Their storage is billed from the end of the seven free days.
- Paid accounts run 100 sandboxes at the same time, not counting paused ones, from the first top-up. A paused sandbox holds no CPU or memory against the account's limits.
Pause when an agent waits
An agent that waits for a person, a webhook or a scheduled job can pause its sandbox for the wait. It keeps everything it had in memory. A coding agent keeps its checkout and its dev server between tasks, as in Claude Code in a sandbox. A pause saves the whole machine. So it suits per-user dev environments that sit idle most of the day. For copies that run side by side, see sandbox forks.
Start
Terminalprintf '%s\n' 'print(sum([125, 250, 375]))' > invoice.pynpx withruntime sandboxes run -- python3 - < invoice.pyA new account gets 100 free hours of a 1 GB machine in its first 30 days, with no card needed. The first run prints a link to approve in your browser. Then use the JavaScript or Python SDK as above.
Facts on this page were checked on 26 October 2026.