Runtime

How to extend a sandbox's lease

Call sbx.extend(seconds) while the sandbox runs; it moves the end of the lease later, up to an hour ahead of now, as often as you need.

On Runtime the end of a lease pauses the sandbox by default instead of deleting it. Files, memory and running processes are kept, so a job that ran over its time can be woken and finished rather than started again. An extension costs nothing on its own; the extra time is billed as it is used, at $0.03125 an hour for a waiting 2 vCPU, 4 GiB sandbox and $0.08 fully busy (pricing, checked 25 September 2026).

Extend a running sandbox

TypeScriptimport { Sandbox } from "withruntime";const sbx = await Sandbox.create({ timeoutSeconds: 600 });console.log("ends at", sbx.info.expiresAt);await sbx.extend(1800); // 30 more minutes before the lease endsawait sbx.refresh();console.log("now ends at", sbx.info.expiresAt);await sbx.stop();
Pythonfrom withruntime import Sandboxsbx = Sandbox.create(timeout_seconds=600)print("ends at", sbx.info["expiresAt"])sbx.extend(1800)  # 30 more minutes before the lease endsprint("now ends at", sbx.refresh().info["expiresAt"])sbx.stop()
Terminalruntime sandbox extend "${id}" 1800   # prints the new end of the lease

Over HTTP it is POST /v1/sandboxes/{id}:extend with {"seconds": 600}, and an agent over MCP calls runtime_sandbox_manage with "action": "extend".

When the lease has already ended

With the default onLeaseEnd: "pause", the sandbox is paused, not gone. A wake gives it a fresh lease, and you choose its length:

TypeScriptimport { Sandbox } from "withruntime";const sbx = await Sandbox.connect(process.env.SANDBOX_ID!);if (sbx.state === "paused") await sbx.wake({ timeoutSeconds: 3600 });await sbx.exec("make test", { timeoutMs: 1_800_000 });
Pythonimport osfrom withruntime import Sandboxsbx = Sandbox.connect(os.environ["SANDBOX_ID"])if sbx.state == "paused":    sbx.wake(timeout_seconds=3600)sbx.exec("make test", timeout_ms=1_800_000)

A request to a paused sandbox also wakes it by itself, with a fresh lease of its own timeoutSeconds.

Lease settings

Setting Default Range or effect
timeoutSeconds 1800 At most 3600: the first lease
extend(seconds) none Moves the end later, up to an hour ahead of now; repeat as often as needed
onLeaseEnd "pause" Or "stop"
wake({ timeoutSeconds }) its own timeout A fresh lease on every wake
keepAlive() off Extends from your process so ten minutes remain, once a minute
persistent: true false Paid only: the lease renews itself on the server while credit lasts
Trial 1800 Each session up to one hour, within the trial's 50 hours

The CLI takes --timeout <seconds> and --on-timeout pause|stop on sandbox create. Python uses timeout_seconds and on_lease_end.

Mistakes to avoid

  • Asking for more than an hour at once. The lease can reach at most an hour ahead of now. For a four-hour job, extend as it goes, let keepAlive do it for you, or make the sandbox persistent.
  • Confusing the lease with a command's timeout. timeoutMs on exec bounds one command (60 seconds by default, 24 hours at most); the lease bounds the machine. A long command needs both.
  • Extending past your daily limit. A key with a daily spending limit refuses an extension past it with spending_limit_reached (HTTP 402), and the SDK does not retry it (security).
  • Relying on your process to stop the sandbox. A host-side lease bounds execution even if management is unavailable, so a crashed script still leaves a sandbox that pauses or stops on time. Keep leases short and extend them rather than asking for the maximum by habit.
  • Choosing "stop" for work you might resume. A stopped sandbox is not a backup. Keep "pause" unless the sandbox holds nothing you need.

Facts on this page were checked on 25 September 2026.