Sandbox lifecycle
How Hotcell sandboxes are created, paused with memory snapshots, resumed, stopped and destroyed, plus idle auto-pause, admission control and warm pools.
States
| Status | Meaning |
|---|---|
creating |
Provisioning. statusReason holds the current phase. Only DELETE is allowed. |
running |
Live and accepting operations. |
paused |
Compute freed, workspace kept. Any operation resumes it automatically. |
stopped |
Stopped by you. It doesn't resume on its own; operations return 409 until you start it. |
error |
Create failed. The reason is in statusReason. Destroy it. |
creating ──▶ running ──(idle > sleepAfter, or pause)──▶ paused ──(any operation)──▶ running
│ │
└──────────────── stop ────────────────────┴──▶ stopped ──(start)──▶ running
Create
hotcell create --image node:22 --memory 2048 --cpus 2 --repo https://github.com/you/app --setup "npm install"
Create options (CLI flag / REST body field):
| Option | CLI | REST field | Notes |
|---|---|---|---|
| Image | --image |
image |
Defaults to HOTCELL_IMAGE |
| Driver | --driver |
driver |
container, firecracker or applevz |
| Environment | --env K=V,… |
env |
|
| Labels | --label K=V,… |
labels |
--name sets the name label |
| Persistent workspace | persist |
Default true |
|
| Idle auto-pause | --sleep-after MS |
sleepAfter |
Milliseconds; 0 disables |
| Repo | --repo URL |
repo |
Cloned into /workspace before setup; a clone failure fails the create |
| Ref | --ref BRANCH |
repoRef |
Branch or tag to check out |
| New branch | --branch NAME |
branch |
Created after the clone; auto generates hotcell/<first 8 chars of id> |
| Setup | --setup "cmd" |
setup (array) |
Runs once after start; best-effort |
| Memory / CPU / PIDs | --memory --cpus --pids |
memoryMb cpus pidsLimit |
Hard caps; override daemon defaults |
| Egress | --egress |
egress |
true or a policy object; see Egress |
| Sandbox spend cap | --egress-spend-cap USD |
egressSpendCapUsd |
|
| Detached | detach |
Return immediately with status creating |
With -n N, the CLI creates N sandboxes in one command and prints one id per line. A shared --name is suffixed per sandbox (feat-1 to feat-N), and so is a named --branch, so pushes don't collide.
Detached creates
A slow create (repo clone plus heavy setup) can outlast a single HTTP request. With detach: true the daemon responds 201 at once with status creating and provisions in the background. The SDKs then poll GET /sandboxes/:id until the sandbox is running, and throw if it reaches error. The CLI's create always uses this path and shows live per-sandbox progress. Ctrl-C leaves provisioning running.
Without detach, a provisioning failure returns 422 and the record is removed.
Setup and custom images
Setup runs once at create time and isn't re-run on resume. With persistence, installed dependencies live in the workspace volume and survive pause and resume. Other ways to arrive with tools installed:
- Build a custom image (extend
images/base/Dockerfile) and setHOTCELL_IMAGE. - Run setup after create:
hotcell exec "$id" "npm i some-cli". - Provision once,
hotcell backup, thenhotcell restoreinto new sandboxes.
Pause and resume
hotcell pause <id>
hotcell resume <id> # or any operation on the sandbox
Pause uses the strongest option the driver offers:
- MicroVM drivers (
firecracker,applevz): a memory snapshot of guest RAM and device state. Background processes come back alive on resume, and tracked processes and exposed ports stay valid. If a snapshot fails to load, the daemon discards it and cold-boots with the workspace intact. - Container driver: stop with volume. The workspace survives; processes, exposed ports and code-interpreter contexts don't.
A paused sandbox resumes on its next operation: exec, file operations, terminal, or inbound traffic on a preview URL. Pausing a stopped sandbox returns 409.
Idle auto-pause
Set sleepAfter per sandbox, or HOTCELL_SLEEP_AFTER_MS as the daemon default (default 0, off). The idle reaper scans every HOTCELL_REAP_INTERVAL_MS (default 15000) and pauses sandboxes idle past their timeout.
- An open exec stream counts as activity for its whole duration.
- Reading metrics doesn't count as activity.
- A sandbox with an exposed port or a tracked background process is auto-paused only if the driver can memory-snapshot it. On the container driver it is skipped, because pausing would kill that work.
Sandboxes never destroy themselves.
Stop and start
hotcell stop <id>
hotcell start <id>
Stop frees compute and keeps the workspace volume. Background processes, exposed ports and code-interpreter contexts end; sessions (working directory and env) are kept. A stopped sandbox stays stopped until you start it.
Destroy
hotcell rm <id> # one or several ids
hotcell rm --all
Destroy removes the sandbox and its persistent volume, its sessions, and all its egress tokens. You can destroy a sandbox while it is creating to cancel the create.
Admission control
The daemon tracks committed memory against a host budget and refuses to over-subscribe:
- The budget is auto-detected (
HOTCELL_HOST_MEMORY_MBandHOTCELL_HOST_CPUSoverride it) and multiplied byHOTCELL_OVERCOMMIT(default1). - A capped sandbox is charged its cap. An uncapped sandbox is charged
HOTCELL_DEFAULT_RESERVATION_MB(default256) until the sampler measures it, then its measured usage. - A create or resume that doesn't fit returns
503withRetry-After: 5. HOTCELL_ADMISSION=offonly reports capacity.
hotcell capacity
Warm pools
A warm pool keeps pre-started sandboxes ready so a create adopts one instead of starting cold. Pools are off by default.
| Driver | Variable |
|---|---|
container |
HOTCELL_CONTAINER_WARM_POOL |
firecracker |
HOTCELL_FC_WARM_POOL |
applevz |
HOTCELL_VZ_WARM_POOL |
- A create adopts a spare only if it matches the pool shape exactly: the daemon's default image and default resource limits.
- Spares are charged to admission capacity.
GET /capacityreports them underpool. - The pool refills in the background as spares are claimed. Beyond pool depth, creates take the cold path.
HOTCELL_CONTAINER_WARM_POOL=10 hotcell start
In a 25-wide container burst on macOS, adopting from a pool had a median create-and-probe time of 517 ms, against 1,845 ms cold. See Benchmarks.
Backups
hotcell backup <id> # snapshot /workspace to a host tarball
hotcell backups [<id>] # list all, or one sandbox's
hotcell restore <id> <backupId> # replace /workspace with a backup
Backups are stored in HOTCELL_BACKUP_DIR (default ~/.hotcell/backups). You can restore a backup into any sandbox, not only the one it came from.