# Sandbox Limits and Pricing

> Sizes, plan limits, timings, what a managed sandbox costs, and the errors you can get.

**URL:** https://inference.sh/docs/extend/sandbox-limits
**Last updated:** 2026-11-09

---

Sizes, plan limits, timings, what a [managed sandbox](/docs/extend/managed-sandboxes) costs, and the errors you can get.

→ [Sandbox quickstart](/docs/extend/sandbox-quickstart) · [Inside a sandbox](/docs/extend/sandbox-environment) · [Sandboxes API](/docs/api/rest/sandboxes)

---

## Sizes

Set the size at create. You cannot resize a sandbox; delete it and create another.

| Field | CLI flag | Default | Max |
|-------|----------|---------|-----|
| `vcpus` | `--vcpus` | 2 | 8 |
| `memory_mib` | `--memory` | 4096 | 16384 |
| `disk_mib` | `--disk` | 10240 | 51200 |

A value of `0`, or no value, takes the default. Anything above the max answers `400` with `<field> must be between 1 and <max>`.

The disk is the box's writable space. The first generation starts empty; later starts reuse the kept disk when `disk_kept` is true. See [Disk](/docs/extend/sandbox-environment#disk).

---

## Who can create sandboxes

Sandboxes are on for every workspace, with one condition: the workspace that pays must have made a purchase in the last 30 days (a card top-up, auto-recharge, subscription payment, or a payment staff recorded). Refunded or disputed payments do not count.

| Case | Create and start | A sandbox already waiting to run |
|------|------------------|----------------------------------|
| No purchase in 30 days | `402` `purchase_required`, with `meta.requirement`, `meta.within_days` and `meta.billing_page` | Stays `pending`; `status_reason` says what is missing |
| `feature:sandboxes` turned off for the workspace | `403` `feature_not_available` | Stays `pending` with `status_reason` `sandboxes are not enabled for this workspace` |

Staff can waive the purchase condition for a workspace. See [Entitlements API](/docs/api/rest/entitlements).

Only the sandbox's owner, or someone with a `write` share on it, can start, stop, delete or exec. Starting a box spends the owner's credit.

---

## Plan limits

Each plan caps the sandboxes a workspace has running and the vCPUs they hold together. A sandbox counts until it is `stopped` or `failed`, including while it is `pending`.

| Plan | Sandboxes (`sandboxes`) | vCPUs (`sandbox_vcpus`) |
|------|-------------------------|--------------------------|
| Starter | 5 | 16 |
| Pro | 10 | 32 |
| Team | 25 | 100 |
| Enterprise | No limit | No limit |

Over a limit, create and start answer `402` `limit_exceeded` with one of:

- `5 of 5 sandboxes in use on your plan: stop or delete one, or upgrade`
- `14 of 16 vCPUs in use on your plan, and this sandbox needs 4: stop or delete one, or upgrade`

Read your usage with [`GET /entitlements/usage`](/docs/api/rest/entitlements#get-usage).

---

## Lifetime

A sandbox has no fixed TTL. By default it **idle auto-stops** after 15 minutes with no API-visible use (execs, harness events on its remote, sandbox changes, or an explicit keep-alive). You can set `idle_timeout_seconds` on create or `PATCH`, or set **0** to disable auto-stop. Details: [Idle auto-stop](/docs/api/rest/sandboxes#idle-auto-stop).

It is billed while running until you stop or delete it, idle auto-stop fires, it runs out of credit, or it fails.

| Timing | Value |
|--------|-------|
| Default idle auto-stop (`idle_timeout_seconds` omitted on create) | 15 minutes |
| Allowed `idle_timeout_seconds` | **0** (never), or **60**–**2_592_000** (30 days) |
| Box must be running after it is sent to an engine | 3 minutes |
| Stop must finish | 60 seconds |
| Remote not connected before the box counts as lost | 3 minutes |
| Remote with no heartbeat before its time stops being billed | 1 minute |
| Automatic restarts | After 5 s, 30 s, then 2 min; at most 3 in 10 minutes, then `failed` |

A box restarts when it ends on its own or its remote is lost. Each restart is a new `generation`. It reuses the kept disk when the engine still holds it; otherwise it boots on a new empty disk.

---

## Commands

| Limit | Value |
|-------|-------|
| `timeout_ms` on [`POST /remotes/{id}/execs`](/docs/api/rest/exec-runs#dispatch-exec-run) | `0` (the default) means no limit |
| `--timeout` on `belt sandbox exec` | Seconds; `0` (the default) leaves it to the server |
| Output chunks per [`GET /execs/{id}/output`](/docs/api/rest/exec-runs#read-output) call | 2000; page with `after_seq` |
| Agent `remote_exec` tool | Default timeout 600 s; the result holds the last 30000 characters of stdout and stderr |

A command still running when its remote disconnects ends `killed`.

---

## Pricing

A sandbox is billed per second for its vCPUs and memory while it is healthy: running, with its remote connected and heartbeating. Time the remote is away or disconnected is not billed. Disk is not billed.

Default prices on platform engines:

| Resource | Price |
|----------|-------|
| vCPU | $0.01 per hour |
| Memory | $0.003 per GiB per hour |

A default sandbox (2 vCPUs, 4 GiB) costs $0.032 per hour, about $0.77 per day left running.

**How it is charged.** At start, the owner's balance holds one hour of the sandbox's price. Each hour, and at stop, the healthy time since the last charge is debited as one `sandbox usage` ledger entry, and the next hour is held. Usage is recorded as vCPU-milliseconds and GiB-milliseconds.

**Out of credit.** A sandbox does not start when the balance is zero or less (`status_reason` `out of credit`). A running sandbox whose next hourly hold is refused is stopped with the same reason. Add credit, then start it again.

→ [Billing API](/docs/api/rest/billing) · [Usage API](/docs/api/rest/usage)

---

## Network

| Rule | Effect |
|------|--------|
| Private, loopback and engine-host addresses | Refused, except the inference.sh API |
| Other sandboxes | Not reachable |
| Inbound connections and public URLs | Not available |
| Crypto-mining pools and the stratum protocol | Refused. After 5 refused attempts the sandbox is stopped with `status_reason` `stopped: egress policy (mining)` |

See [Network](/docs/extend/sandbox-environment#network).

---

## Errors

| Status | Code or message | Cause | What to do |
|--------|-----------------|-------|------------|
| `400` | `<field> must be between 1 and <max>` | Size above the max | Use a size in [Sizes](#sizes) |
| `400` | `mode is auto or ask, not "<mode>"` | Bad `credentials[].mode` | Use `auto` or `ask` |
| `402` | `purchase_required` | No purchase in 30 days | Top up at the `meta.billing_page` link |
| `402` | `limit_exceeded` | Plan limit reached | Stop or delete a sandbox, or upgrade |
| `403` | `feature_not_available` | Sandboxes are off for the workspace | Contact support |
| `403` | `insufficient_scope` | Key lacks `sandboxes:read` or `sandboxes:write` | Use a key with those scopes |
| `404` | | Not found, or not yours | Check the id; list with `belt sandbox list` |
| `409` | `this sandbox is being deleted` | Start after delete | Create a new sandbox |
| `409` | `the sandbox is changing; try again` | Two changes raced | Retry |
| `409` | `sandboxes are not set up on this server (no SANDBOX_IMAGE)` | Self-hosted API without a box image | Set `SANDBOX_IMAGE` |
| `412` | `errors` per credential | A `credentials` login is not connected | Connect it, or use `mode: ask` |

Exec on a sandbox's remote can also answer `403` `exec_disabled` or `409` `remote_offline`; see [Exec runs API errors](/docs/api/rest/exec-runs#errors). `belt sandbox exec` refuses before it calls the API when the sandbox is not `running`.

In the CLI, these map to [exit codes](/docs/extend/cli-setup#exit-codes): `2` usage, `4` auth, `5` not found, `6` permission denied, `9` payment, `1` for the rest (including `409`).

`status_reason` says why a sandbox is `pending`, `stopped` or `failed`. Values include `no capacity`, `no engine online`, `out of credit`, `the engine went away`, `the box did not start within 3m0s`, and `stopped: egress policy (mining)`.
