Skip to content

Add Sandboxes documentation page - #24

Open
mmilutinovic371 wants to merge 5 commits into
mainfrom
docs/sandboxes
Open

Add Sandboxes documentation page#24
mmilutinovic371 wants to merge 5 commits into
mainfrom
docs/sandboxes

Conversation

@mmilutinovic371

Copy link
Copy Markdown

Summary

New docs page for the DeepSands sandbox service (isolated microVMs for running untrusted code), added ahead of general release per mentor feedback that pre-release docs matter — especially the non-obvious details (lifespan, /workspace-only persistence, isolation boundaries).

  • New page: sandboxes/overview.mdx, added to nav between GPU Instances and Hosted Agents
  • Content verified directly against the backend implementation (deep-sands service) and the deepinfra-python SDK source, not just the marketing blog post — plans/pricing table, lifecycle states, three independent timeout clocks (idle / 24h hard age / 7-day stopped retention), filesystem persistence model, isolation/networking, quotas, typed errors, Python SDK usage, and raw HTTP API examples
  • Note: docs use /workspace (not /work) for all paths — the backend only accepts /workspace; the SDK's own README/examples currently use /work, which is a separate bug worth fixing in that repo

Test plan

  • Validated docs.json is well-formed JSON
  • Ran npx mint broken-links — no broken links
  • Visual check with mint dev (not run in this environment)

mmilutinovic371 and others added 3 commits August 14, 2026 12:37
Documents the DeepSands sandbox service ahead of release: plans/pricing,
lifecycle and timeouts, filesystem persistence (only /workspace survives
stop/start), isolation/networking, quotas, errors, Python SDK, and HTTP API.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Exact specs and hourly rates can change; link to the dashboard and
catalog endpoint/SDK method instead of a table that will go stale.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The backend branch merged main since the page was first written, and
fixed the fs-path-outside-/workspace bug from a 500 to a proper 400 --
update the docs to match instead of describing a bug that's gone.
Also: drop the unreachable 403 row from the errors table, add the 400
row that's now common (bad path, empty command, timeout out of range),
note the read-side 100 MiB cap symmetric to writes, and mention the
fail_reason field GET/list now returns for a failed sandbox.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Comment thread sandboxes/overview.mdx Outdated
A sandbox is subject to three independent clocks:

- **Idle timeout** — configurable per sandbox with `timeout` at creation (an hour, by default, if you don't pass one, and there's currently no way to disable it). Idle time is measured from when your **last call finished**, not when it started, so a single command that runs longer than the idle timeout can have its sandbox stopped out from under it mid-execution. If a job might take a while, set `timeout` generously (up to the 30-minute per-command cap) rather than relying on the default.
- **24-hour hard age limit** — a sandbox auto-stops 24 hours after **creation**, and that clock is never reset by `stop()`/`start()`. Create a sandbox, stop it after ten minutes, come back the next day, and it can auto-stop again shortly after you restart it — simply because it's more than a day old by wall-clock time. If you need something to outlive a day of calendar time, `terminate()` and recreate it rather than stop/start-ing the same one indefinitely.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To be honest, this flow doesn't seem right to me. Let's refactor the logic to: a sb can be in running state max 24h at a time, then it becomes stopped. Also, a stopped sb is deleted after 7 days of inactivity. In theory someone might start and stop his sb forever, but that's not a problem for us and he will be paying for the time it's running.

Comment thread sandboxes/overview.mdx
- **File transfers** — both `fs.write()` and `fs.read()` are capped at 100 MiB per call (see above).
- **Disk** — scales with plan (see the [catalog](#plans-and-pricing) for exact numbers); the container's own disk outside `/workspace` is only a couple GB regardless of plan.

## Tags

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

did you implement tags while I was out...?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actually, tags were implemented early on, at the beginning of DeepSands - I just forgot about them, they've been tested and verified

Comment thread sandboxes/overview.mdx

The Python SDK adds a few client-side exceptions for conditions that aren't a single HTTP response: `SandboxTimeoutError` (waiting for a state transition took too long), `SandboxFailedError` (the sandbox went to `failed` while you were waiting on it), `SandboxExecError` (the exec stream ended without a return code), and `CommandFailedError` (raised by `.check()` on a non-zero exit).

## Python SDK

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please make sure both the python sdk and the http api examples all work - copy and paste them to verify

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

verified - everything good

Comment thread sandboxes/overview.mdx
icon: cube
---

Sandboxes give you an isolated Linux microVM on demand, ready to run code the moment it boots and torn down the moment you're done with it. They're built for agents and pipelines that need to execute arbitrary or untrusted code without you having to build and operate that infrastructure yourself.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add another short paragraph, please:

Sandboxes are ephemeral by design: they're short-lived, and data inside them is not backed up or guaranteed to persist while they run. Treat a sandbox as scratch space — write anything you want to keep to external storage before it shuts down.

mmilutinovic371 and others added 2 commits August 19, 2026 16:18
…examples

- backend#4450 (merged) changes the 24h sandbox lifetime cap to measure
  continuous running time instead of wall-clock age since creation, so
  stop()/start() now resets it -- update both mentions and drop the
  now-misleading terminate()-and-recreate guidance.
- Add an ephemeral-by-design paragraph to the intro per PR review
  feedback from ats3v.
- Make the async SDK example actually runnable (bare `await` outside a
  function is a SyntaxError) and annotate fs.read()'s bytes return type
  on the context-manager example, both prompted by user confusion.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
stop() and terminate() don't check suspension (sandbox_routes.py) --
only create/start/exec/fs calls do. The old text implied stop was
blocked too, which would have stopped suspended users from cutting
off their own billing.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants