Sandboxes
A Sandbox is MIOSA’s fast code execution environment. Your agent writes files into it, executes commands, exposes ports as live preview URLs, and snapshots state for branching or rollback. Use it for build loops, tests, scripts, package installs, code generation, preview servers, and short-lived automation.
Sandboxes are persistent by default.
When you pause them or their timeout expires, MIOSA preserves the filesystem and moves the session to paused so it can resume later.
Destroy only when the saved state should be removed.
What Sandboxes are for
Generate code, edit files, install dependencies, run tests, and stream logs back to the agent.
Run a web server in the sandbox and expose only the needed port as an HTTPS preview URL.
Isolate untrusted commands from your backend while keeping filesystem state scoped to the sandbox.
Snapshot working state, resume later, or fork from a known point for parallel agent work.
What a Sandbox is, concretely
- Isolated compute for code generation, builds, tests, and dev servers.
- Named, versioned CPU, memory, and disk contracts plus per-sandbox timeout and environment parameters.
/workspaceis the editable filesystem root.- Boots from a versioned template, usually
miosa-sandbox. - Persistent by default, so
timeout_secstops compute and preserves state instead of deleting the workspace. - Network-isolated by default.
- Preview URLs open only the specific ports you expose.
- Destroy is permanent and removes the saved state.
Configuration vs per-sandbox parameters
Platform configuration defines what can be selected: template aliases, immutable image generations, named resource contracts, readiness, placement policy, and tenant limits.
Customers inspect that configuration with GET /api/v1/templates; applications do not send internal placement, host, or provider fields.
Per-sandbox parameters select behavior for one sandbox.
They include template_id, size, timeout_sec, always_on, persistent, and idle_timeout_sec.
Prefer a named size over raw CPU, memory, and disk fields.
If compatibility fields are used, cpu_count, memory_mb, and disk_size_mb must be supplied together and exactly match one published contract.
The default is small: 2 vCPU, 4096 MiB RAM, and 10240 MiB disk. xs is available for lighter work when the template catalog reports it for the selected template and current readiness permits admission.
Every sandbox response includes a versioned resource_contract, such as sandbox/small@v1, so clients can record the resolved resources instead of assuming a size name will never evolve.
{
"template_id": "miosa-sandbox",
"size": "small",
"timeout_sec": 3600,
"persistent": true,
"idle_timeout_sec": 0
} Sandbox vs Computer vs App Engine
| Need | Product | Result |
|---|---|---|
| Run commands, edit files, install packages, test code | Sandbox | Isolated runtime with exec, files, snapshots, and preview URLs |
| Use a browser login, desktop app, screenshots, mouse, keyboard | Computer | Durable GUI machine with streaming and desktop control |
| Publish a 24/7 app for users | App Engine | Always-on deployment URL with custom domain support |
Sandboxes are excellent for building and previewing. They are not the final production hosting layer. When a preview becomes a user-facing app, publish it through App Engine so it gets the right routing, domains, lifecycle, and billing behavior.
Core capabilities
| Capability | What it gives you |
|---|---|
exec.run | Blocking command execution with stdout, stderr, exit code, and duration |
exec.stream | Real-time stdout/stderr events for long builds or installs |
files.write/read/list/stat | Direct filesystem access under /workspace and other allowed paths |
previews.create | Public HTTPS URL for a running process on a specific sandbox port |
snapshot | Durable checkpoint for resume, fork, or rollback |
pause / resume | Stop compute without discarding saved state |
Lifecycle
| State | Meaning |
|---|---|
creating / provisioning | VM is being claimed, restored, and prepared to accept commands |
running | Command-ready: exec, files, previews, terminal, and port exposure work |
snapshotting | Runtime is saving filesystem and memory state for resume/fork |
paused | CPU is stopped; memory/filesystem state is preserved for resume |
destroyed | Terminal: resources freed, ID unusable, saved state removed |
error | Boot or runtime failure; check sbx.data["metadata"] for last_error |
Activity that resets the idle clock: exec calls, file writes, preview HTTP traffic, terminal stdin. For persistent sandboxes, once timeout_sec elapses the running session stops and the sandbox becomes paused. For explicitly non-persistent sandboxes, timeout destroys the VM and discards the filesystem.
See Persistence, pause, and forks for the full pause/resume/fork flow.
Current production benchmark
On June 9, 2026, MIOSA ran a historical production sandbox benchmark through the real HTTP API: 100 sandboxes, concurrency 10, template miosa-sandbox, size small.
These measurements predate the current image and provisioning architecture and are retained as a dated baseline, not current production performance.
Result: 100 / 100 sandboxes completed create -> ready -> exec -> destroy, with 0 capacity rejections.
| Path | What it measures | p50 | p95 | p99 |
|---|---|---|---|---|
POST /api/v1/sandboxes/run | Fused create -> wait -> first exec, the optimized agent path | 512ms | 992ms | 1.300s |
POST /api/v1/sandboxes + poll + /exec | Standard client-owned lifecycle | 947ms | 1.333s | 1.348s |
See Benchmarks for methodology, caveats, and the difference between VM boot time and full command-ready time.
Fast path: create and run
For agents that need a sandbox and immediately run the first command, use the fused run endpoint. It is faster because MIOSA owns the readiness wait on the server and avoids an extra client poll loop plus a second public exec request.
Response shape:
{
"data": {
"id": "sbx_a1b2c3d4",
"state": "running",
"template_id": "miosa-sandbox",
"ready": true
},
"exec": {
"stdout": "2\n",
"stderr": "",
"exit_code": 0
},
"timings": {
"server_wait_and_exec_ms": 512
}
} Create with full options
Use full create when you need to provision the sandbox first, write files, start a preview server, attach databases, or keep the ID for a longer session.
The response body contains id, state, template_id, size, resource_contract, cpu_count, memory_mb, and created_at. Save the id; every
subsequent call needs it.
Context manager (auto-destroy)
The Python SDK supports with / async with; the sandbox is destroyed on exit
even if an exception is raised:
Connect to an existing sandbox
Run a command: exec
exec.run blocks until the process exits and returns stdout, stderr, exit_code, and duration_ms.
Stream stdout/stderr in real time
exec.stream returns an iterator of SSE events. Use this for long commands (builds, test runs, installs) where you want to surface output progressively.
Files: write, read, list, stat
All file paths are absolute. Parent directories are created automatically on write. File content is base64-encoded over the wire.
Filesystem layout
| Path | Purpose |
|---|---|
/workspace | Agent working directory: write all app code here |
/home/sandbox | User home |
/tmp | Scratch space: cleared on destroy |
/opt/venv | Pre-installed Python virtualenv (miosa-sandbox, python templates) |
/usr/local/bin | System binaries |
Previews: expose a port
previews.create maps a sandbox port to a public HTTPS URL managed by MIOSA. The URL is live as long as the sandbox is running.
See Previews for visibility controls, custom domains, and embedding.
Snapshots and forks
A fork creates a new sandbox from a copy-on-write snapshot of a running sandbox. The source remains unchanged and the new sandbox receives its own lifecycle and timeout. Standalone snapshot create, list, restore, and delete operations are available through the CLI and API. Use snapshot IDs returned by MIOSA and verify restored workloads before redirecting traffic.
curl -X POST https://api.miosa.ai/api/v1/sandboxes/$SBX/fork
-H "Authorization: Bearer $MIOSA_API_KEY"
-H "Content-Type: application/json"
-H "Idempotency-Key: fork-experiment-001"
-d '{"timeout_sec": 3600}' See Snapshots for the direct snapshot lifecycle.
Pause and resume
pause() and resume() give you explicit control over the running ↔ paused transition without destroying state.
Environment variables
Env vars set at create time are injected into the VM at boot and visible to all processes. They are read-only once the sandbox is running; env.list() returns the live set.
Subscribe to sandbox events
The events.stream() endpoint emits lifecycle and activity SSE events for a
sandbox, which is useful for monitoring agent runs.
List and filter sandboxes
Timeout and usage
timeout_sec is the active-session timeout, defaults to 3600 seconds, and accepts values from 1 through 86400. POST /api/v1/sandboxes/{id}/extend replaces that timeout; it does not add seconds to the previous value.
An omitted extend body preserves the current timeout.
Set always_on: true only when policy permits a sandbox to run until an explicit lifecycle action.
GET /api/v1/sandboxes/{id}/usage returns runtime_sec, provisioned_vcpu_ms, active_cpu_ms, network ingress and egress bytes, estimated cost, and timeout visibility. runtime_sec and provisioned_vcpu_ms are allocation measurements.
Use measurement_status before interpreting active CPU or network values:
| Status | Meaning | Client behavior |
|---|---|---|
measured | The value was measured for this sandbox. | Display and aggregate it normally. |
unavailable | No trustworthy measurement is available. The related value is null. | Show “Unavailable”; never coerce it to zero. |
stale | The value is the latest retained sample but is not current. | Label it stale and avoid presenting it as real-time usage. |
Provisioned resources are always reported with measurement_status.provisioned_resources: "measured". timeout_remaining_ms can be null before start or when timeout enforcement is disabled.
Sizing reference
| Size name | vCPU | RAM | Disk | Notes |
|---|---|---|---|---|
xs | 1 | 2 GB | 10 GB | Lightweight scripts |
small | 2 | 4 GB | 10 GB | Default for agent and build workloads |
medium | 4 | 8 GB | 20 GB | Larger builds and parallel tests |
large | 8 | 16 GB | 40 GB | Heavy test suites |
xl | 16 | 32 GB | 80 GB | Intensive parallelism |
Use the default small contract for Claude Code, Codex, package installation, ordinary application builds, and agent execution.
Choose medium only when measured CPU, memory, or disk requirements exceed small.
Raw resource fields are compatibility inputs and must exactly identify a published named contract.
Raw resource overrides (still accepted):
| Field | Default | Validation range |
|---|---|---|
cpu_count | 2 | 1-16 |
memory_mb | 4096 | 2048-32768 |
disk_size_mb | 10240 | Must match the selected named contract |
timeout_sec | 3600 | 1-86400 |
idle_timeout_sec | 0 (disabled) | 0-86400 |
always_on | false | Not required for most agent work |
persistent | true | Preserve sandbox state across pauses and resumes |
Set always_on=True to disable timeout_sec enforcement entirely. Useful for long-lived development environments or hosted IDEs. Set idle_timeout_sec to stop an abandoned persistent session after a period of inactivity. Set persistent=False only for one-off jobs where the filesystem should be discarded on stop or timeout.
Custom templates
A template is selectable only after it appears in GET /api/v1/templates with a size that is fast_ready or cold_boot_only; missing sizes are unavailable.
Standalone custom-template build and promotion operations are not part of canonical public V1.
Contact MIOSA for preview access rather than depending on uncontracted build endpoints.
Production checklist
Before relying on sandboxes in production:
- Set an explicit
timeout_sec. Interactive app-building workflows should usually use1h; short one-shot commands can use less. - Keep the default
persistent=Truefor agent workspaces so timeout preserves/workspaceand dependency installs. - Set
idle_timeout_secfor user-facing dev environments so abandoned sessions stop compute and preserve state. - Pass
idempotency_keyonsandboxes.createcalls in agent retry loops. The platform deduplicates creates with the same key within a 24-hour window. - Use a published template instead of reinstalling the same dependencies for every sandbox.
- Fork before destructive operations when you need an independent branch of the current running state.
- Subscribe to
sbx.events.stream()to detect unexpected exits and trigger retries. - Never store long-lived secrets in
env; pass them per-exec or use the Secrets API. - Filter by
external_workspace_idin your list calls to avoid scanning your entire tenant’s sandbox set.
Billing notes
Billing accrues from state = "running" until state = "paused" or state = "destroyed".
- Running: billed at the vCPU-second + GiB-second rate for your plan
- Paused: billed at storage rate only (disk GiB-second)
- Destroyed: billing stops immediately
Template readiness and available sizes are reported by the catalog and can vary by environment.
See also
Full filesystem and process API: recursive operations, watch, detached jobs.
Live HTTPS URLs proxied to a sandbox port with share tokens and visibility controls.
Built-in images and custom BuildSpec reference.
Pause, resume, fork, and the current public snapshot boundary.