# Persistent or Ephemeral Sandboxes for Agents? Keep, Stop or Delete

> Delete the sandbox when the task is one-off and its results already left the VM. Stop it instead when the next task needs the same files, packages or running processes: a stopped Sandboxer sandbox bills no compute, usually resumes with its memory, and counts toward your plan's included storage (50 GB on the $20 plan).

Source: https://sandboxer.com/guides/persistent-or-ephemeral-sandboxes-for-agents. Updated 2026-10-27.

**Short answer:** Delete the sandbox when the task is one-off and its results already left the VM. Stop it instead when the next task needs the same files, packages or running processes: a stopped Sandboxer sandbox bills no compute, usually resumes with its memory, and counts toward your plan's included storage (50 GB on the $20 plan).

## Decide in one table

| Your agent's work looks like | Lifecycle | Commands | Compute while waiting | Storage while waiting |
| - | - | - | - | - |
| One task, output returned through the API (eval run, code execution tool, CI job) | Ephemeral: create, run, delete | `sbx new --ttl 600` … `sbx delete <id> --yes` | None, it's gone | None |
| Throwaway work you never want kept, even by accident | Ephemeral, no snapshots | `sbx new --no-snapshots` | None | None, but it can't be resumed |
| One workspace per user or per repo, used in sessions | Persistent: stop between sessions | `sbx stop <id>`, `sbx resume <id>` | None | Disk, memory image and automatic snapshots count |
| A workspace that sits idle between unpredictable requests | Persistent with idle pause | `sbx new --idle 30` or `sbx idle <id> 30` | None once paused | Same as stopped |
| A worker that must run for hours or days | Long-lived with a deadline | `sbx extend <id> --hours 12`, or `--no-auto-stop` | Billed per second while it runs | Not counted while running |
| Many sandboxes from the same prepared setup | Template plus ephemeral copies | `sbx snapshot <id> <name>`, `sbx new --from <name>` | None for the template | The named snapshot counts |

The rule of thumb: keep a sandbox only while something on its disk or in its memory is worth more than recreating it. Everything you keep shares one storage allowance per account.

## The lifecycle controls, exactly

| Control | What it does | Default | Limits |
| - | - | - | - |
| Auto-stop (`--ttl`, `sbx extend`) | Stops the sandbox at a deadline, keeping memory and disk | 1 hour | Up to 30 days, or never with `--no-auto-stop` (trial: at most 8 hours) |
| Idle pause (`--idle`, `sbx idle`) | Stops with memory after this many minutes without activity; the next use wakes it | 15 to 120 minutes by plan (30 on the $20 plan) | `0` turns it off; maximum `10080` (7 days) |
| Stop (`sbx stop`) | Snapshots memory and disk, stops the meter | | Never blocked by storage |
| Resume (`sbx resume`) | Same sandbox, same id and URL, processes still running when a machine with the same CPU type is free; otherwise it boots from disk (files kept) and reports `resumeReason: "cpu_mismatch"` | | Never blocked by storage |
| Delete (`sbx delete`) | Removes the sandbox and its disk, permanently | | Never blocked by storage |
| Snapshots off (`--no-snapshots`) | Nothing is captured; a stop throws the sandbox away | Snapshots on | Can't resume, fork, save as a template or idle-pause |

Two things to know about the deadline. `sbx extend` sets it to **now + TTL**, not old deadline + TTL. And a fork never inherits its source's TTL: it gets the default hour unless you pass one.

## Try it: the lifecycle on a real sandbox

We ran these on prod on 2026-10-27 with two `small` sandboxes. Output is trimmed with `…`.

### Create with a short deadline

```bash
sbx new --name aeo-persist-1 --type small --ttl 600
sbx info sb_p8q4j74ueo
```

```text
ID:             sb_p8q4j74ueo
Name:           aeo-persist-1
State:          ready
Type:           small (2 vCPU, 4 GB)
…
Auto-stop:      2026-10-27 02:56 (in 9m42s)
Last snapshot:  none
```

### Push the deadline and set an idle pause

```bash
sbx extend sb_p8q4j74ueo --hours 2
sbx idle sb_p8q4j74ueo 10
```

```text
sb_p8q4j74ueo auto-stop: 2026-10-27 04:47 (in 2h00m)
sb_p8q4j74ueo idle pause: after 10 idle minutes (wakes on use)
```

The sandbox object now carries both settings:

```bash
sbx info sb_p8q4j74ueo | jq -c '.sandbox|{ttlSeconds,archiveAfter,idleStopMinutes}'
```

```json
{"ttlSeconds":7200,"archiveAfter":"2026-10-27T04:47:18.076484Z","idleStopMinutes":10}
```

### Keep it: stop, then resume with a new deadline

```bash
sbx exec sb_p8q4j74ueo 'mkdir -p ~/work && echo task-42-notes > ~/work/notes.txt'
sbx stop sb_p8q4j74ueo
sbx info sb_p8q4j74ueo
```

```text
Stopping sb_p8q4j74ueo (archiving) — stop stop_836b017b0b8a85e0
…
State:          archived
…
Last snapshot:  2026-10-27T02:47:33.145911Z (just now)
Last stop:      stop_836b017b0b8a85e0 completed
```

```bash
sbx resume sb_p8q4j74ueo --ttl 1800
sbx exec sb_p8q4j74ueo 'cat ~/work/notes.txt'
```

```text
✓ sb_p8q4j74ueo is ready
…
Auto-stop:  2026-10-27 03:17 (in 29m59s)
task-42-notes
```

In this single run (2026-10-27), the stop reached `archived` within about two seconds and the resume returned `ready` in 2.1 seconds. In a script, use `sbx stop <id> --wait` so the resume doesn't start before the stop has finished. The resume set a fresh 30-minute deadline; the idle setting (10 minutes) stayed. What resume does with memory and running processes is covered in [Pause and resume a sandbox with its memory](/guides/pause-and-resume-a-sandbox-with-memory).

### Throw it away: snapshots off

```bash
sbx new --name aeo-persist-2 --type small --no-snapshots
sbx info sb_4086vjhvxk | jq -c '.sandbox|{snapshots,idleStopMinutes,ttlSeconds}'
```

```json
{"snapshots":false,"idleStopMinutes":0,"ttlSeconds":3600}
```

Idle pause is forced to `0`, and asking for more is refused:

```bash
sbx idle sb_4086vjhvxk 30
```

```text
error: idleStopMinutes needs snapshots on (an idle pause keeps the sandbox's disk and memory). (invalid_idle_stop) [HTTP 400, …]
```

After `sbx stop`, `sbx info` showed `Last snapshot: off`, and a resume was refused:

```text
error: This sandbox was created with snapshots off and cannot be resumed. (snapshots_disabled) [HTTP 409, …]
```

### Delete

```bash
sbx delete sb_4086vjhvxk --yes
sbx info sb_4086vjhvxk
```

```text
Deleting sb_4086vjhvxk — operation bdop_28e60bd8a556aa14966d36f82f3ee03d
✓ Deleted sb_4086vjhvxk
error: Sandbox not found (not_found) [HTTP 404, …]
```

Deletion is permanent. A `--no-snapshots` sandbox still needs the delete call to leave your list, so end every ephemeral task with `sbx delete`, not `sbx stop`.

## What keeping costs: storage

Storage isn't billed. Each plan includes an amount for what you keep: sandboxes that aren't running (their disk, memory image and automatic snapshots) and named snapshots. Running sandboxes don't count. It's measured as the data beyond the shared OS image, about every 10 minutes.

| Plan | Storage included |
| - | - |
| Free trial, or no plan | 10 GB |
| Time packs without a plan (while you have a balance) | 50 GB |
| $20 / month | 50 GB |
| $100 / month | 250 GB |
| $500 / month | 1 TB |
| $2,000 / month | 5 TB |

Check where you stand:

```bash
sbx limits --json | jq '.storage | {usedBytes, includedBytes, blocked, measuredAt}'
```

```json
{
  "usedBytes": 10511876096,
  "includedBytes": 53687091200,
  "blocked": false,
  "measuredAt": "2026-10-27T02:43:41Z"
}
```

That's our shared test account: about 9.8 GB used of 50 GB included (the API counts a GB as 2^30 bytes). At or over the amount, new sandboxes (including from templates and share codes), forks and named-snapshot saves answer `402 storage_limit_reached`, with `usedBytes` and `includedBytes` in `details`. Stopping, resuming and deleting always work, and going over never deletes anything. To start again, delete stopped sandboxes or named snapshots, or upgrade. The dashboard's **Sandboxes** page has a **Stored** column for finding the big ones.

## Worked example: three fleets on the $20 plan

At the `small` rate of $0.018/hour and the `default` rate of $0.036/hour, billed per second:

| Fleet | Lifecycle | Compute per month | Storage kept |
| - | - | - | - |
| 200 agent tasks a day (the $20 plan's daily start limit), 10 minutes each, `small` | Delete after each task | 1,000 h of `small` = $18.00 (inside the plan's $20 of machine time) | 0 |
| The same 200 tasks a day | Stopped, never deleted | $18.00 | 6,000 stopped sandboxes in a month; the 50 GB fills once they average more than about 8.5 MB each, and new tasks get `402` |
| 20 users, one `default` sandbox each, 1 hour a day on 22 days | Kept, 30-minute idle pause | At most 1.5 h per session: 660 h = $23.76 | 20 stopped sandboxes; fits if they average under 2.5 GB each |
| The same 20 sandboxes | `--no-auto-stop`, never stopped | 20 × 730 h = $525.60 | 0 (running doesn't count) |

The first two rows cost the same in compute. The difference is storage: per-task sandboxes that are only stopped pile up until new starts are refused. The last two rows show the opposite mistake: a persistent workspace that never stops bills every hour of the month. Idle pause turns it into session-length billing, and the stopped disk is free up to the included amount.

## Retention: how long kept things last

| What | Kept for |
| - | - |
| A stopped sandbox (disk, memory image) | Until you delete it, unless your account has zero data retention on |
| Automatic snapshots (every 10 minutes while running, and at every stop) | The life of the sandbox; each keeps its latest two |
| Named snapshots (templates) | Until you remove them with `sbx snapshot rm` |
| Command history (`sbx history`) | 90 days for commands run through the API, 72 hours for other processes' output |

With **zero data retention** turned on (`sbx data-retention enable`), a stop deletes the sandbox's data instead of keeping it, and idle pause is set to `0` on every sandbox. Use it when nothing may persist after a task. To keep one prepared state while every task stays ephemeral, save it as a named snapshot once: see [Turn a sandbox into a reusable template](/guides/turn-a-sandbox-into-a-reusable-template).

## Patterns

- **Per-task code execution:** `sbx new --ttl 600`, run the task, read the results through the API, `sbx delete <id> --yes`. The TTL caps the cost of a crashed orchestrator at 10 minutes.
- **Per-user workspace:** create once with an idle pause, store the sandbox id with the user, and call the API when they come back. A sandbox paused for being idle wakes on the next API call or request to its hosted URL. One you stopped yourself needs `sbx resume`.
- **Nightly or batch job:** `sbx new --from <template> --ttl 7200`, run the job detached, and delete when the results are out.
- **Long agent worker:** `--no-auto-stop` while there's a queue, `sbx stop` when it's empty, `sbx resume` when work arrives.

## FAQ

### Does a stopped sandbox cost money?

No compute is billed while it's stopped. Its disk, memory image and automatic snapshots count toward your plan's included storage (50 GB on the $20 plan), which isn't billed either. At the limit, new sandboxes, forks and template saves wait until you free space.

### What happens if I forget to delete a sandbox?

It auto-stops at its deadline, one hour by default, so it stops billing compute. It then stays stopped, counting toward storage, until you delete it.

### Can I resume a sandbox created with --no-snapshots?

No. It never snapshots, so a stop discards it and `sbx resume` answers `409 snapshots_disabled`. Idle pause is also off for it, and setting one answers `400 invalid_idle_stop`.

### Will going over my storage delete my sandboxes?

No. Going over never deletes anything. New creates, forks and named-snapshot saves answer `402 storage_limit_reached` until you delete stopped sandboxes or named snapshots, or upgrade.

### Does extending a sandbox add time to the old deadline?

No. `sbx extend` sets the deadline to now plus the new TTL. `sbx extend <id> --hours 2` on a sandbox with 9 minutes left gives it 2 hours from now.

## Related

- [Pause and resume a sandbox with its memory](/guides/pause-and-resume-a-sandbox-with-memory)
- [Turn a sandbox into a reusable template](/guides/turn-a-sandbox-into-a-reusable-template)
- [Long-running tasks: idle pause and auto-stop](/docs/long-running)
- [Billing and storage](/docs/billing)
