Skip to main content
A sandbox is one microVM with its own kernel, disk and memory. It runs Ubuntu 24.04 with Docker and common toolchains. You make it, run commands in it, fork it, snapshot it, stop it, start it and delete it.

Lifecycle

Create, fork, stop, start and delete return once the change is done. While it is in progress the sandbox shows a transitional status. What each status allows: Anything else returns HTTP 409 with code invalid_state, for example “sandbox is stopped; start it to run commands”.

Sizes

The host accepts only these four. A sandbox made without a size is small, in the API, the SDK, the CLI and the MCP server. The size named default is not the default: you get 4 vCPU only when you ask for default. On the CLI, pass --size. In the API and SDK, pass vcpus (2, 4, 8 or 16); RAM and disk follow. Any other combination returns 400 with the list of available sizes. A sandbox made from a custom image has the image’s size, and a fork has its parent’s. A sandbox’s size does not change after it is made.

Names and ids

Every sandbox has an id like sbx_d54teouhd5f4lf52 and a name. Names are 1 to 63 characters of a-z, 0-9 and -, and cannot start or end with -. Leave the name out and Zode picks a two-word one such as brave-hopper. Names do not have to be unique. The CLI accepts a name or an id; when two sandboxes share a name it asks you for the id. The API and SDK take ids only.

Regions

Sandboxes run in eu-central, on Google Cloud in europe-west1 (Belgium). It is the only region today. US East is coming soon. The API takes an optional region; an unknown region returns 400. A sandbox made from a custom image runs in the image’s region.

Stop or delete

Stopping hibernates the sandbox. Its memory and disk are saved, running processes resume where they were when you start it again, and compute billing stops. Storage is still billed while it is stopped. Deleting removes the sandbox, its disk and its snapshots. Billing for it ends. You cannot undo a delete. Forks of a deleted sandbox keep working.
Storage is free for the first 48 hours of every sandbox, forks included. After that it is billed at $0.10 per GB-month until delete, whether the sandbox is running or stopped. It is measured on the sandbox's full disk size, so a `small` sandbox (50 GB) costs $5 a month in storage on top of its compute once it is two days old. Delete sandboxes you no longer need. See Pricing. A stopped sandbox starts again on the same host. If that host has no free memory at that moment, start returns 409 node_full; try again shortly.

Exec and attach

There are two ways to run something in a sandbox. Buffered exec, POST /v1/sandboxes/{id}/exec, runs one command and returns exit_code, stdout, stderr and duration_ms in one response. Pass command (a string, run under bash -lc) or argv (run as is). The working directory defaults to /workspace. env entries are added to the default environment and the sandbox’s environment; on a clash yours win. Limits: 30 seconds by default and 55 seconds at most (timeout_ms), 16 KB of command, 1 MiB of stdin, and 1 MiB each of stdout and stderr (beyond that the response sets stdout_truncated or stderr_truncated). Attach, GET /v1/sandboxes/{id}/attach, is a WebSocket that streams output both ways, supports a TTY and has no time limit. See Attach. The CLI uses attach for both zode exec and zode ssh. zode exec streams output and exits with the command’s exit code. With exactly one argument after --, the command runs through bash -lc, so quote shell syntax as one argument. With several arguments, they run as is, with no shell:
The SDK’s exec() uses the buffered route and switches to attach when you stream output, ask for a TTY, pass a timeout over 55 seconds or more than 1 MiB of stdin. A bare exec() with no timeout is killed after 30 seconds. If the kernel kills a command for running out of memory, the result says so (oom_killed and peak_rss_mb in the API; “killed: out of memory” from the CLI).

Repo, branch and PR labels

You can label a sandbox with the git repo, branch and pull request it works on. Zode does not clone anything: the labels are for cost breakdowns. zode cost --by repo (or branch, pr) groups spend by them, as does the console’s Usage page.
The API fields are git_repo (up to 512 characters), git_branch (up to 255) and pr_number (positive). The CLI flags are --repo, --branch and --pr. A fork keeps its parent’s repo; you can give it a new git_branch and pr_number (zode fork --branch B --pr N). Labels cannot be changed after the sandbox is made.

Per-sandbox spend cap

max_cost_micros caps a sandbox’s AI provider spend, in millionths of a dollar (5000000 is $5). It counts only model calls the sandbox makes through Zode’s AI proxy that are paid by an API key. Compute, storage and calls made through a signed-in subscription are not counted. When the cap is reached, further model calls from that sandbox get HTTP 402 with code zode_spend_cap, and a spend.cap_reached alert fires. The sandbox keeps running, and its compute and storage are not counted against this cap.
  • Leave it out and the sandbox gets the workspace’s default per-sandbox cap from Billing, if one is set. 0 or no default means no cap.
  • A fork inherits its parent’s cap unless you pass a new one.
  • The cap is set at create or fork and cannot be changed afterwards.
  • The host keeps the running total in memory, so a host restart resets it.
On the CLI, pass --max-cost in dollars to zode new or zode fork; in the SDK, maxCostMicros. Workspace-wide daily caps are on Spend and caps.

Limits

  • Running at once: Free 2, Pro 15, Team 50; a Pro trial gets Pro’s 15. Sandboxes that are creating, running or starting count; stopped ones do not. Over the limit, create, fork and start return 409 concurrency_limit.
  • Credit: a workspace with no card on file and no credit left cannot create, fork or start sandboxes (402 credit_exhausted), and its running sandboxes are stopped. See Pricing.
  • Create rate: creates and forks are limited to 30 an hour per user, 60 an hour per workspace and 60 an hour per client IP. Over it you get 429 rate_limited with Retry-After and X-RateLimit-* headers.
  • Daily cap: if your workspace has a daily spend cap and today’s spend (UTC) has reached it, create, fork and start return 409 daily_cap_reached.
  • Same host: a fork runs on its parent’s host, and a stopped sandbox starts on its own host. When that host has no free memory you get 409 node_full.
  • Free plan: a sandbox that averages 90% CPU or more for an hour, or that looks like it is scanning the network, is stopped. So are the workspace’s running sandboxes once it sends more than 10 GiB out in a UTC day.