# How to keep a sandbox running A Runtime sandbox already runs while it works, with no time limit. `persistent: true` keeps a paid sandbox running even while it is idle. **On Runtime, a sandbox can run for as long as the account has credit. You set a spending ceiling, and the sandbox is billed only for the CPU it uses.** A busy sandbox is never stopped by a timer, and nothing needs renewing. A persistent 2 vCPU, 4 GiB sandbox that waits most of the day costs $0.03125 an hour, about $22.50 over 30 days. With both CPUs busy, it costs at most $0.08 an hour ([pricing](/docs/pricing), checked 25 October 2026). After a stop, its disk is kept, so it restarts where its files left off. ## Which to use | Need | Use | When it pauses | | ------------------------------------------------------- | -------------------- | ------------------------------------------- | | A job, an agent run, a notebook or a CI step | Nothing: the default | After 300 seconds with nothing happening | | A server, bot or dev box that runs with nobody watching | `persistent: true` | Never on its own. You stop it | | A sandbox created with a time limit, held past it | `keepAlive()` | When your process lets it go | ## A persistent sandbox ```ts check import { Sandbox } from "withruntime"; const server = await Sandbox.create({ name: "api-bot", persistent: true, maxTotalCostMicros: 50_000_000, // at most $50 over its life }); await server.spawn("python3 -m http.server 8000"); // Later: it was stopped, and its disk was kept. await server.restart(); await server.update({ persistent: false }); // back to an ordinary sandbox ``` ```python check from withruntime import Sandbox server = Sandbox.create(name="api-bot", persistent=True, max_total_cost_micros=50_000_000) server.spawn("python3 -m http.server 8000") server.restart() # after a stop, from its kept disk server.update(persistent=False) ``` ```bash no-run id=$(runtime sandboxes create --persistent --name api-bot) runtime sandboxes update "${id}" --persistent on --max-total-cost 50 # dollars runtime sandboxes restart "${id}" ``` A name stays held while its sandbox is stopped and persistent. So `Sandbox.getOrCreate("api-bot")` finds the sandbox and restarts it for you. An agent over MCP calls `runtime_sandboxes_manage` with `"action": "persist"`. A stopped persistent sandbox stays in `runtime ls` while its disk is kept. To be done with it, turn persistence off: `runtime sandboxes update "${id}" --persistent off` deletes a stopped sandbox's disk and frees its name. On a running sandbox, it ends the disk charge immediately. ## A long job needs nothing A sandbox created without `timeoutSeconds` runs for as long as its job does. A two-hour training run is not cut off at one hour. When the job ends and nothing else happens, the sandbox pauses itself. ```ts check import { Sandbox } from "withruntime"; const worker = await Sandbox.create(); await worker.exec("python3 train.py", { timeoutMs: 7_200_000 }); // two hours await worker.stop(); ``` ```python check from withruntime import Sandbox worker = Sandbox.create() worker.exec("python3 train.py", timeout_ms=7_200_000) # two hours worker.stop() ``` `keepAlive()` is for a sandbox created with a time limit. It moves the limit on from your process, keeping ten minutes ahead. It keeps doing this until you call `stop()`, or until you call the function it returns. ## What each costs and keeps | Setting | Detail | | --------------------- | ------------------------------------------------------------------------------------------------------------------------------- | | `persistent` | Paid only; runs until you stop it, idle or not, while the account has credit | | `maxTotalCostMicros` | The most the sandbox may cost over its whole life; `--max-total-cost` in dollars | | After a stop | The disk is kept, billed as paused storage, and `restart()` starts it again | | Reserved disk rate | 153 microdollars per GiB-hour, the volume rate, about $0.11 per GiB a month | | Idle pause | 300 seconds with nothing happening by default; `idlePauseSeconds` sets 0 (never) or 60 to 86,400 | | Compute while running | $0.025 per active vCPU-hour of measured CPU, $0.0075 per reserved GiB-hour | | Out of credit | Sandboxes and stored items are kept 30 days with a notice (seven without a purchase or saved card), then deleted | ## Mistakes to avoid - **Making a sandbox without credit persistent.** Persistence is for paid sandboxes. Once the account holds credit, its sandboxes are paid and can be persistent. - **No ceiling.** Without `maxTotalCostMicros`, a persistent sandbox runs for as long as credit lasts. Set a ceiling, or a daily spending limit on the key ([security](/docs/security)). - **Starting the server with `exec`.** A process started by `exec` ends with its command. Use `spawn` so the server keeps running. - **Setting a time limit you then have to keep extending.** Leave `timeoutSeconds` out. The sandbox then runs while it works, with nothing for your process to keep alive. - **Keeping it running only to keep its state.** If nobody uses it for hours, [pause it when idle](/how-to/pause-when-idle) instead. Memory and processes come back on the next request. ## Related - [Extend a sandbox's time limit](/how-to/extend-a-sandbox-lease), for one created with a limit. - [Find a sandbox by name](/how-to/find-a-sandbox-by-name) to reach a long-running one from anywhere. - [Run a background process](/how-to/run-a-background-process) for the server itself. - [Keep a sandbox running](/docs/javascript#keep-a-sandbox-running) in the SDK reference. Facts on this page were checked on 25 October 2026.