Skip to content
Guides · Agent cookbook

How Do I Cap What Agent Sandboxes Can Cost?

Updated October 27, 2026 .md

Short answer: Stack the levers that exist. Per sandbox, pick a small size, a short TTL and an idle timeout, and delete it when the task ends. Per key, give agents scoped, expiring keys. Per account, your plan's concurrency and start limits, a prepaid balance without auto-refill and alerts set the ceiling. A watchdog deletes stragglers.

There is no "max dollars per sandbox" setting. What you get instead is a set of controls that each bound one dimension: how fast a sandbox burns time, how long it can run per start, how many can run at once, how many can start per day, and how much balance there is to spend. This page lists every one we could find in the docs and the API, shows which ones we tested on prod, and links the watchdog that catches the rest. For the price tables themselves, see sandbox cost tables.

Every lever, at a glance#

Lever Scope What it bounds Set with Stops a running sandbox?
Size Sandbox Burn rate: small is 0.5× default type / --type No
TTL (auto-stop) Sandbox Run time per start ttlSeconds / --ttl, sbx extend Yes, at archiveAfter
Idle timeout Sandbox Run time with nothing happening idleStopMinutes / --idle, sbx idle Yes, pauses it
Delete on finish Sandbox Everything after the task, plus storage sbx delete --yes, DELETE /sandboxes/{id} Yes
Scoped, expiring key Key Which actions an agent can take, and until when sbx api-key create --actions … --ttl … No
In-sandbox token Sandbox Code inside can't create, extend or delete sandboxes Automatic (SANDBOXER_TOKEN) No
Concurrency limit Account Sandboxes active at once (100 on the $20 plan) Your plan No, refuses new ones
Start limits Account Creates, resumes and forks per minute, hour, day Your plan No, refuses new ones
Prepaid balance, auto-refill off Account Total machine time you can spend Billing page, sbx billing autorefill Yes, after a 24-hour grace
Alerts Account Nothing: they notify you Dashboard Alerts No
Member caps Organization One member's sandboxes at once, and machine time per plan period Organization owner (usage cap: API only) No, refuses new ones

We tested the per-sandbox levers and the in-sandbox token on prod. We did not change any account-level setting (plan, auto-refill, alerts, keys) on the shared test account; those rows come from the billing, limits, API keys and organizations docs.

The ceiling, as arithmetic#

Prices come from the pricing page: default costs $0.036 an hour, and small costs $0.018 an hour. A dollar buys 100,000 seconds of default time.

One sandbox. Its worst case per start is TTL × hourly rate. A small sandbox with a 15-minute TTL: 0.25 h × $0.018 = $0.0045 per start. The same sandbox with --no-auto-stop and idle pause off can run the whole month: 730 h × $0.018 = $13.14.

A runaway fleet, per hour. Your concurrency limit caps how many run at once. On the $20 plan that's 100. If all 100 are default: 100 × $0.036 = $3.60 for each hour they all run. If you only ever create small: 100 × $0.018 = $1.80.

A runaway fleet, per day. Every create, resume, fork and wake on use counts as a start, and each start gets at most one TTL of run time. So, as long as nothing extends a sandbox or turns auto-stop off, run time per day is at most starts per day × TTL. On the $20 plan (200 starts a day) with a 1-hour TTL: 200 × 1 h = 200 h. At the default rate that's 200 × $0.036 = $7.20; for small, 200 × $0.018 = $3.60. Without TTLs the concurrency limit is the only bound: 100 × 24 h × $0.036 = $86.40 a day.

The account. With auto-refill off, the balance is the hard ceiling: your plan's included time plus any packs you bought. On the $20 plan that's 2,000,000 seconds of default time ($20 × 100,000), or 555 hours of default.

Per sandbox: size, TTL, idle timeout#

Set all three when you create the sandbox, so a sandbox the agent forgets about still stops. We created a small sandbox through the REST API with a 15-minute TTL, a 10-minute idle timeout and two labels to find it by later:

curl -sS -X POST https://sandboxer.com/api/v1/sandboxes \
  -H "Authorization: Bearer $SANDBOXER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name":"agent-job-1","type":"small","ttlSeconds":900,"idleStopMinutes":10,
       "labels":{"job":"agent-job","tenant":"demo"}}'
{
  "id": "sb_wp6oo0ktg2",
  "name": "agent-job-1",
  "state": "provisioning",
  "type": "small",
  "ttlSeconds": 900,
  "idleStopMinutes": 10,
  "archiveAfter": "2026-10-27T10:51:57.1552Z",
  "labels": { "job": "agent-job", "tenant": "demo" }
}

The response was 202 (trimmed with jq), and the sandbox was ready five seconds later. archiveAfter is creation time plus 900 seconds. The CLI equivalent is sbx new --type small --ttl 900 --idle 10 --name agent-job-1; labels are REST and MCP only (labels).

Three details that change the arithmetic:

  • The TTL counts from each start, not from creation. sbx extend --ttl sets the deadline to now + TTL, and a resume or a wake on use starts a fresh TTL window. A sandbox that idles, wakes, idles and wakes can run indefinitely in TTL-sized pieces. Only deleting it ends that.
  • Idle pause stops compute, not storage. A paused sandbox bills no compute, but its disk and memory count toward your plan's included storage. The idle defaults are 15 to 120 minutes depending on your plan; see idle auto-pause for what counts as activity.
  • --no-auto-stop removes the per-start bound. We turned it on and back off on our sandbox:
sbx extend sb_wp6oo0ktg2 --no-auto-stop
sbx --json info sb_wp6oo0ktg2 | jq '.sandbox | {ttlSeconds, archiveAfter, idleStopMinutes}'
sbx extend sb_wp6oo0ktg2 --ttl 600
sbx --json info sb_wp6oo0ktg2 | jq '.sandbox | {ttlSeconds, archiveAfter, idleStopMinutes}'
{ "ttlSeconds": null, "archiveAfter": null, "idleStopMinutes": 10 }
{ "ttlSeconds": 600, "archiveAfter": "2026-10-27T10:47:09.249674Z", "idleStopMinutes": 10 }

With auto-stop off, the idle timeout is the only thing left that stops it, and only when nothing is using it. A dev server polled by a health check, a ~/.sandboxer/keep-awake file or a load average of 0.5 or more keeps it awake. If a sandbox needs --no-auto-stop, keep its idle timeout on and give it a label your watchdog skips. On the free trial, TTLs above 8 hours and --no-auto-stop are refused (400 trial_auto_stop_required).

Per sandbox: delete when the task ends#

A stopped sandbox bills no compute, but it still holds storage, and when storage is full new sandboxes answer 402 storage_limit_reached. For agent work that leaves nothing worth keeping, delete in a finally block, so a crash in the tool call still cleans up:

sbx delete "$id" --yes

The REST call is DELETE /sandboxes/{id} with the header X-Sandboxer-Confirm-Delete set to the sandbox id. A fresh sandbox per tool call shows the create-run-delete loop with timings. A watchdog catches the ones a finally misses: a killed process, a lost network, a deploy mid-task.

Per key: scoped, expiring keys#

API keys can't carry a dollar limit or a TTL ceiling, but they can limit which actions a caller may take and expire on their own. Two patterns from the API keys docs:

# The backend that runs agents: create, run, delete only what it created; expires in 30 days
sbx api-key create agent-runner --preset ci --ttl 30d
# The watchdog: read and delete, nothing else
sbx api-key create sandbox-watchdog --actions sandbox.read,sandbox.delete --ttl 90d

We didn't run these: creating keys changes the shared test account. The ci preset includes sandbox.delete-own, which deletes only sandboxes that key created. A key without sandbox.create, sandbox.resume and sandbox.fork can't start anything, so it can't add cost at all.

A key with sandbox.create can still ask for "ttlSeconds": null or xlarge. If an agent picks the arguments, don't give it the key. Have your backend create sandboxes with the size and TTL you choose, and expose only "run this command" to the model. The MCP server's sbx mcp --type small --ttl 1800 sets defaults for sandboxes the agent creates without those arguments; it is not a ceiling.

The token inside the sandbox can't add cost#

Code running in a sandbox gets SANDBOXER_TOKEN, a key limited to that sandbox. We tried to use it from inside our sandbox to create a large sandbox and to turn off its own auto-stop:

sbx exec sb_wp6oo0ktg2 -- bash -c 'curl -sS -X POST https://sandboxer.com/api/v1/sandboxes \
  -H "Authorization: Bearer $SANDBOXER_TOKEN" -H "Content-Type: application/json" \
  -d "{\"type\":\"large\"}"'
{"code":"api_key_action_forbidden","error":{"code":"api_key_action_forbidden","details":{"action":"sandbox.create"},"message":"This API key does not allow sandbox.create.","status":403}, …}

The same token sending PATCH /sandboxes/sb_wp6oo0ktg2 with {"ttlSeconds":null} got 403 api_key_action_forbidden with "action":"sandbox.update". An agent with a shell can't spawn more sandboxes or keep its own running past the TTL, as long as you don't put a broader key in its environment.

Per account: limits, balance, alerts#

None of these were changed in our test. They come from the docs and the API.

  • Concurrency and start limits. Your plan sets how many sandboxes can be active at once and how many starts you get per minute, hour and day. Going over returns 429 limit_reached, rate_limited or daily_limit_reached. Check what's left with sbx limits --json | jq '.starts'. See rate limits and concurrency.
  • Prepaid balance with auto-refill off. This is the closest thing to a hard spend cap. When the balance reaches zero, new creates, resumes and forks fail with 402 billing_required, the account owner gets an email, and running sandboxes keep running for a 24-hour grace period, then stop with memory and disk kept. With auto-refill on, packs are bought automatically below your threshold, so there is no ceiling. Check it with sbx billing.
  • Alerts. The dashboard's Alerts page has four rules: balance falls below N hours, spend in the last 24 hours (rolling, at list price) exceeds N dollars, a sandbox runs longer than N hours, and start-limit usage reaches N% of a limit (checked against the per-minute, per-hour and per-day start limits). Each sends an email or a webhook, and each rule fires at most once per 24 hours per subject. Alerts notify only; nothing is stopped.
  • Organization member caps. An organization owner can cap a member's concurrent sandboxes (429 member_limit_reached) and a member's machine time with the API: PATCH /orgs/{orgId}/members/{userId} with usageCapSeconds, counted in machine-time seconds from the start of the plan period (or over the last month without a plan). Once it's reached, the member's creates, resumes and forks get 402 team_member_cap_reached; running sandboxes keep running. clearUsageCap: true removes it. The usage cap is API-only (organizations). Giving each agent service its own member is a way to give it its own budget.

A watchdog that deletes stragglers#

The levers above bound the damage; a watchdog removes what's left. Run it from cron with a server-side label filter, a dry run by default, and an age threshold a bit above your longest real task. Clean up orphaned sandboxes has the full script, with the label query, paging and the confirmation header a delete needs.

We ran a small Python version against our sandbox, filtered by its label and name prefix. A 60-minute threshold matched nothing, a 0.5-minute one matched it, and the --delete run removed it:

would delete sb_wp6oo0ktg2 agent-job-1 ready small age=0.6m
deleted sb_wp6oo0ktg2 agent-job-1 ready small age=0.7m

sbx --json info sb_wp6oo0ktg2 answered 404 not_found (exit code 4) in the same second. For cost, two choices matter:

  • Delete or stop. Deleting also frees storage. To keep the data, list with state=ready,idle,running and call POST /sandboxes/{id}/stop instead.
  • Give it its own key. A key with only sandbox.read and sandbox.delete can't start anything, so the watchdog itself can't add cost.

Keep the watchdog as the backstop. The primary path is still deleting in your own code when the task ends.

What our test cost#

sbx usage read the meter while the sandbox ran: 19 seconds of default time after 40 seconds of wall time, because small runs at 0.5×. That's 19 / 100,000 = $0.00019. The whole test, including the in-sandbox calls, ran from 10:36:57 to 10:37:37 UTC on October 27, 2026, with no errors from the platform.

FAQ#

Is there a hard dollar limit per account?#

Not as a separate setting. The prepaid balance is the hard ceiling when auto-refill is off: new starts stop at zero and running sandboxes stop after a 24-hour grace period. Alerts can warn you before that.

Does the TTL limit a sandbox's total lifetime?#

No. It limits each run. A resume, a wake on use or sbx extend sets a new deadline of now + TTL. To end a sandbox for good, delete it.

Can an agent inside a sandbox start more sandboxes?#

Not with the token it gets. We tried from inside: SANDBOXER_TOKEN got 403 api_key_action_forbidden for sandbox.create and for changing its own TTL. Don't put a broader key in the sandbox's environment.

Does a stopped or paused sandbox cost anything?#

No compute. Its disk and memory count toward your plan's included storage, and when that's full new sandboxes are refused until you delete some.

Can I give one API key its own budget?#

No: keys limit actions, sandboxes, environments and expiry, not spend. For a separate budget, use an organization member with a usage cap, or enforce one in your backend with sbx usage per sandbox.

More guides

Top AI sandbox platforms for code execution in 2026, ranked

For running AI-written code we rank Sandboxer, Freestyle and E2B first: each gives code its own VM with an API or SDK and can pause with memory. Pick Daytona for Windows or GPUs, Modal or Northflank for GPUs at scale, E2B or Northflank to run in your own cloud, and Vercel Sandbox if your app lives on Vercel.

Read the guide
Best sandboxes for running coding agents (Claude Code, Codex, Gemini CLI) in 2026, ranked

For coding agents we rank Sandboxer first: a full Ubuntu VM with Claude Code and Codex preinstalled, Docker, and stop-and-resume that keeps the agent's session in memory. Freestyle and Amp Orbs also keep memory across pauses. Pick E2B for prebuilt agent templates on open source, Docker Sandboxes for free local runs, and Codespaces if you live in GitHub.

Read the guide
Best Daytona sandbox alternatives in 2026, ranked

The best Daytona alternatives depend on why you're switching. For a full Linux microVM on every sandbox with memory-saving stop and Docker, we rank Sandboxer first. E2B suits open source and self-hosting, Modal massive short-job fleets, Northflank bring-your-own-cloud with GPUs, and Vercel Sandbox apps on Vercel.

Read the guide
Best E2B alternatives in 2026, ranked

If you're leaving E2B for longer sessions or a fuller machine, we rank Sandboxer first, then Freestyle: both give each sandbox a full Linux VM that keeps memory across pauses, with Docker and no short session cap. Pick Daytona for Windows or GPUs, Northflank for bring-your-own-cloud, and stay on E2B if you need open source.

Read the guide