On Runtime (withruntime.com), a paused sandbox keeps every process and variable where the agent left it. A sandbox also pauses itself after 300 seconds with no activity, so the default already does the right thing. This post explains why pausing is better than both deleting and keeping the sandbox running. It includes the cost calculation for a real conversation.
What are the three ways to handle the gap between turns?
Between two turns of an agent conversation, you can delete the sandbox, leave it running, or pause it. Each choice has a different cost.
| Between turns | What the next turn finds | What the gap costs | Latency added to the next turn |
|---|---|---|---|
| Delete it | A blank machine; setup runs again | Nothing | A new sandbox, plus every setup step |
| Keep it running | Everything as it was | Memory and CPU floor, every minute | None |
| Pause it | Everything as it was, processes included | Storage for what it alone holds | A wake before the next command |
Deleting looks cheapest, and keeping the sandbox running looks fastest. Pausing keeps the state of a running sandbox at close to the cost of a deleted one.
What does deleting a sandbox throw away?
Deleting removes everything the agent built that is not in your source code. Most of it is slow to rebuild.
After a few turns, a coding agent's sandbox typically holds:
- Installed packages.
npm installorpip install -r requirements.txttook tens of seconds and pulled hundreds of megabytes. - Build output and caches. Compiled objects, a test runner's cache, a type checker's incremental state.
- Running processes. A dev server on port 3000, a database the tests use, a watcher, a language server the agent queries.
- Interpreter state. Variables in a Python or Node REPL: a loaded DataFrame, an open connection, a trained model held in memory.
- The agent's scratch work. Notes, half-finished patches, downloaded files, shell history.
You can save and restore files on disk by hand. Processes and memory cannot be restored that way. Only a pause or a snapshot keeps them. A data agent loads a 2 GB CSV into pandas. After a delete, it repeats that load on every turn. A paused sandbox keeps the DataFrame in memory, so the next turn starts with it already loaded.
What does a wake cost in time?
A wake loads the saved memory back; it repeats no setup. npm ci on a
mid-sized project alone takes longer than a wake. The speed
guide lists an operation's time once it is within 2× of its floor, the wake's included, measured each minute from
outside.
You do not have to wake a sandbox yourself. A paused sandbox wakes on its own
when a request needs it: an exec, a file call, a process or terminal call,
or a visit to one of its shared ports. The call waits while the sandbox wakes,
then runs (wake a sandbox on request).
What does a conversation cost each way?
Consider one user's afternoon with a coding agent: 12 turns over two hours, with a message every ten minutes. Each turn keeps the sandbox busy for 45 seconds and uses 20 CPU-seconds of work. The sandbox has 2 vCPU and 4 GiB of memory. Its saved state is about 1 GB.
Kept running for the whole two hours, the sandbox is billed for memory and the CPU floor for the entire time:
- Running 2 hours
- 2 × $0.03125 + 12 × 20 / 3,600 × $0.025
- $0.0642
Paused between turns, it runs 45 seconds per turn, waits 300 seconds, and then pauses itself. For the rest of the time, it is billed only for paused storage:
- Running
- 12 × (45 + 300) s / 3,600 × 4 GiB × $0.0075
- $0.0345
- CPU
- 12 × 20 / 3,600 × $0.025
- $0.0017
- Paused
- 1 GB × $0.08 / 720 hours × 2 hours
- $0.0002
- Total
- $0.0364
That is 43% less than keeping it running, for exactly the same experience.
Deleted after each turn, with 40 seconds of setup that uses 50 CPU-seconds before every turn:
- Running
- 12 × (40 + 45) s / 3,600 × 4 GiB × $0.0075
- $0.0085
- CPU
- 12 × (50 + 20) / 3,600 × $0.025
- $0.0058
- Total
- $0.0143
Your own setup time decides how much deleting costs. Measure it once, in a new sandbox, with the steps your agent runs before its first useful command:
TypeScriptimport { Sandbox } from "withruntime";const setup = [ "git clone --depth 1 https://github.com/pallets/flask.git app", "cd app && pip install --quiet -e .",];await using sbx = await Sandbox.create();const started = Date.now();for (const step of setup) await sbx.exec(step, { check: true, timeoutMs: 300_000 });console.log(`setup: ${Date.now() - started} ms, paid again on every turn after a delete`);Pythonimport timefrom withruntime import Sandboxsetup = ["git clone --depth 1 https://github.com/pallets/flask.git app", "cd app && pip install --quiet -e ."]with Sandbox.create() as sbx: started = time.monotonic() for step in setup: sbx.exec(step, check=True, timeout_ms=300_000) print(f"setup: {(time.monotonic() - started) * 1000:.0f} ms, paid again on every turn after a delete")Deleting is not cheaper than pausing. It costs about the same and adds 40 seconds of setup to every turn. The user feels that delay. The numbers change with the size of your project, but the pattern holds: one paused hour of storage costs $0.000111 per GB, and one running idle hour of this sandbox costs $0.03125.
How do you build a conversation around pause?
Give each conversation a sandbox with a name based on the conversation, and
have every turn find it by that name. getOrCreate returns the sandbox if it
exists, wakes it if it is paused, or creates it:
TypeScriptimport { Sandbox } from "withruntime";export async function handleTurn(conversationId: string, command: string) { const sbx = await Sandbox.getOrCreate(`chat-${conversationId}`, { labels: { kind: "chat" }, idlePauseSeconds: 60, // the user reads the answer; no need to wait five minutes }); if (!sbx.info.reused) { await sbx.exec("pip install --quiet pandas pyarrow", { check: true, timeoutMs: 300_000 }); } const result = await sbx.exec(command, { cwd: "/workspace", timeoutMs: 120_000 }); await sbx.pause(); // the turn is over: stop paying for compute now return result;}Pythonfrom withruntime import Sandboxdef handle_turn(conversation_id: str, command: str): sbx = Sandbox.get_or_create( f"chat-{conversation_id}", labels={"kind": "chat"}, idle_pause_seconds=60, # the user reads the answer; no need to wait five minutes ) if not sbx.info.get("reused"): sbx.exec("pip install --quiet pandas pyarrow", check=True, timeout_ms=300_000) result = sbx.exec(command, cwd="/workspace", timeout_ms=120_000) sbx.pause() # the turn is over: stop paying for compute now return resultThree details make this work:
- The name is the key. A name is unique in the account while its sandbox
can still run. Every turn of
chat-42reaches the same machine, from any server process.info.reusedsays whether setup already ran. - Pause at the end of the turn.
pause()returns once the sandbox's processors have stopped, and compute billing ends at that moment. The idle pause is the safety net for a turn that crashes before it reaches that point. - Set the idle time to match your usage.
idlePauseSecondstakes 60 to 86,400 seconds. A chat that pauses explicitly can use a short value. A sandbox that serves a preview to a person who clicks around needs a longer one.
If your agent loop calls the model from outside the sandbox, the sandbox can pause while the model generates a response. The next tool call wakes it. The wake adds less time than the model's own response time.
How long does a paused sandbox keep its state?
A paused sandbox on paid credit keeps its state while the account has credit, or for the 1 to 365 days you set. Each pause replaces the saved state from the previous pause. A conversation that lasts for months keeps only its latest state. A sandbox without credit keeps its state for seven days at no charge. Each paused sandbox gets an account notice one day before its saved state is deleted (paused storage).
For state that must outlast any one sandbox, such as a user's files over months, also write it to a volume or to your own bucket (agent memory that persists).
When should you delete instead?
Delete the sandbox when nothing is worth keeping, or when keeping it would be
wrong. A one-shot job that returns its result has no next turn. An eval task
must start clean every time, so a reused machine would make the score
unreliable. When a conversation has ended for good, return its storage:
delete() removes the disk and paused memory immediately.
In short
- Between turns, pausing keeps processes, memory and files. Deleting keeps nothing, and running keeps charging.
- For a two-hour, 12-turn conversation, pausing costs a fraction of keeping the sandbox running, and about the same as deleting, without the setup on every turn.
- Name each conversation's sandbox and use
getOrCreate, pause at the end of each turn, and let idle pause handle the rest. - Delete when the work is truly over or must start clean.
Run it on Runtime
Runtime costs 42% to 88% less than fourteen other sandbox providers for an agent that mostly waits on a model (compare costs). Every Runtime sandbox pauses itself after 300 seconds with no activity, keeps its memory and processes, and runs its next command when a request wakes it. Paused, it costs $0.08 per decimal GB per 30-day month, with no compute charge (pricing). Start free, with 100 free hours of a 1 GB machine every month, without a credit card: sign in or read get started.