# How to keep a sandbox running Create it with `persistent: true` to keep a paid sandbox running while credit lasts, or call `keepAlive()` to hold it from your process. **On Runtime a sandbox can run for as long as the account has credit, with a spending ceiling you set, and still bill only the CPU it uses.** A persistent 2 vCPU, 4 GiB sandbox that waits most of the day costs $0.03125 an hour, about $22.50 over 30 days, and $0.08 an hour at most with both CPUs busy ([pricing](/docs/pricing), checked 25 September 2026). After a stop its disk is kept, so it restarts where its files left off. ## Two ways, for two jobs | Need | Use | Who renews the lease | | ------------------------------------------------------- | ------------------ | --------------------------- | | A server, bot or dev box that runs with nobody watching | `persistent: true` | Runtime, on the server | | A job, a notebook or a CI step that owns the sandbox | `keepAlive()` | Your process, once a minute | ## A persistent sandbox ```ts check import { Sandbox } from "withruntime"; const server = await Sandbox.create({ name: "api-bot", funding: "paid", 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 lease ``` ```python check from withruntime import Sandbox server = Sandbox.create(name="api-bot", funding="paid", 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 sandbox create --paid --persistent --name api-bot) runtime sandbox update "${id}" --persistent on --max-total-cost 50 # dollars runtime sandbox restart "${id}" ``` A name stays held while its sandbox is stopped and persistent, so `Sandbox.getOrCreate("api-bot")` finds it and restarts it for you. An agent over MCP calls `runtime_sandbox_manage` with `"action": "persist"`. ## Keep it alive from your process `keepAlive()` extends the lease so ten minutes remain, once a minute, until you call `stop()` or the function it returns. When your process ends, the lease runs out as usual and the sandbox pauses, by default. ```ts check import { Sandbox } from "withruntime"; const worker = await Sandbox.create({ keepAlive: true }); // on from the start const release = worker.keepAlive({ marginSeconds: 1800 }); // or with options await worker.exec("python3 train.py", { timeoutMs: 7_200_000 }); release(); await worker.stop(); ``` ```python check from withruntime import Sandbox worker = Sandbox.create() release = worker.keep_alive(margin_seconds=1800) worker.exec("python3 train.py", timeout_ms=7_200_000) release() worker.stop() ``` ## What each costs and keeps | Setting | Detail | | --------------------- | ---------------------------------------------------------------------------------- | | `persistent` | Paid only; the lease renews itself on the server 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 reserved disk, and `restart()` starts it again | | Reserved disk rate | 153 microdollars per GiB-hour, the volume rate, about $0.11 per GiB a month | | `keepAlive()` | Extends so ten minutes remain, once a minute; `marginSeconds` asks for more | | Compute while running | $0.025 per active vCPU-hour of measured CPU, $0.0075 per reserved GiB-hour | | Out of credit | Paused sandboxes and stored items are kept seven days, with a notice, then deleted | ## Mistakes to avoid - **Making a trial sandbox persistent.** Persistence is for paid sandboxes. Pass `funding: "paid"` (`--paid`) once the account has credit. - **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. - **Counting on `keepAlive` after your script exits.** It runs in your process; the lease stops renewing when the process does. Anything that must outlive the script needs `persistent`. - **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 lease](/how-to/extend-a-sandbox-lease) by hand. - [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 September 2026.