# How to cap what a single sandbox can cost Pass `maxTotalCostMicros` for a ceiling over the sandbox's whole life, or `maxCostMicros` to refuse a create whose first lease costs more. **On Runtime the cap is held by the server, per sandbox, so a runaway agent or a forgotten long-lived machine stops at the figure you chose.** Because CPU is billed on measured use, the cap also lasts longer than on a provider that bills allocated vCPUs: $50 covers 625 fully busy hours of a 2 vCPU, 4 GiB sandbox at $0.08 an hour, or 1,600 hours of it waiting at $0.03125 (rates checked 25 September 2026, [pricing](/docs/pricing)). ## Two caps, two questions | Setting | Question it answers | When it acts | What you see | | -------------------- | ------------------------------------- | ---------------------------------- | ---------------------------------------- | | `maxCostMicros` | May this create start at all? | At create, against the first lease | The create is refused | | `maxTotalCostMicros` | How much may this sandbox cost, ever? | While it runs, renewals included | It stops; `stopReason` is `lifetime_cap` | Money is in microdollars: 1,000,000 is one US dollar. Neither has a default, and both can be set on the same create ([the create body](/docs/api#sandboxes)). ## Set both on a create ```ts import { Sandbox } from "withruntime"; await using sbx = await Sandbox.create({ vcpu: 2, memoryMiB: 4096, timeoutSeconds: 1800, maxCostMicros: 1_000_000, // refuse to start if the first lease could cost over $1 maxTotalCostMicros: 5_000_000, // stop after $5 over its whole life }); console.log((await sbx.exec("nproc")).stdout); ``` ```python from withruntime import Sandbox with Sandbox.create(vcpu=2, memory_mib=4096, timeout_seconds=1800, max_cost_micros=1_000_000, max_total_cost_micros=5_000_000) as sbx: print(sbx.exec("nproc").stdout) ``` ## Cap a sandbox that renews itself A `persistent` paid sandbox renews its own lease on the server while the account has credit. That is what a long-lived agent or dev server wants, and it is also the case a lifetime cap is made for. ```ts check import { Sandbox } from "withruntime"; const server = await Sandbox.create({ funding: "paid", persistent: true, maxTotalCostMicros: 50_000_000, // at most $50 over its life }); await server.update({ maxTotalCostMicros: 80_000_000 }); // raise it later; null removes it ``` ```python check from withruntime import Sandbox server = Sandbox.create(funding="paid", persistent=True, max_total_cost_micros=50_000_000) server.update(max_total_cost_micros=80_000_000) ``` ```bash no-run runtime sandbox update "${id}" --persistent on --max-total-cost 50 # dollars here ``` The CLI takes dollars; the SDKs and the API take microdollars. After a stop, a persistent sandbox keeps its disk, billed as reserved disk, so `restart()` brings it back. ## Other limits that bound cost | Control | What it bounds | | ----------------------- | ------------------------------------------------------------ | | `timeoutSeconds` | One lease: 1,800 seconds by default, at most 3,600 | | `onLeaseEnd` | `"pause"` (the default) or `"stop"` when the lease ends | | `idlePauseSeconds` | Pauses after 60 to 86,400 seconds with no request | | `cpu`, `cpuFloorMillis` | The waiting charge: a higher floor or `"reserved"` raises it | | A key's daily limit | Everything one agent's key commits in any 24 hours | A paused sandbox stops billing compute at once and costs $0.08 per decimal GB of saved state per 30-day month, so `onLeaseEnd: "pause"` with an idle pause is the cheapest way to keep a machine around ([pause and resume](/how-to/pause-and-resume-a-sandbox)). ## Mistakes to avoid - **Dollars in the SDK.** `maxTotalCostMicros: 50` is fifty microdollars, not fifty dollars. Write `50_000_000`. - **A `maxCostMicros` below the lease you asked for.** A first lease of a large shape for an hour can cost more than a small cap allows, and the create is refused. Lower `timeoutSeconds` or the size, or raise the cap; the hint says which. - **Expecting a lifetime cap to pause.** At the cap the sandbox stops. Its `stopReason` is `lifetime_cap`; start a new sandbox if the work needs more ([a sandbox stopped on its own](/docs/troubleshooting#a-sandbox-stopped-on-its-own)). - **A persistent sandbox with no cap.** It runs for as long as the account has credit. Give it `maxTotalCostMicros`, or give its key a [daily spending limit](/how-to/set-a-daily-spending-limit). - **Counting storage as covered by the cap.** Images, volumes and kept snapshots are charged as storage on their own ([storage prices](/docs/pricing#snapshots-images-and-volumes)). ## Check what a sandbox cost `runtime usage` prints the balance and what each kind of resource was charged, and `runtime usage --json` gives every figure in integer microdollars. To see what the same work would cost elsewhere, `runtime compare --from e2b` prices your last 30 days at the rival's published rates. For estimates before you run, use the [sandbox cost calculator](/calculators/sandbox-cost-calculator). Facts on this page were checked on 25 September 2026.