Set these when you create the sandbox, or on the call that uses them (a command, a fork, a port URL). A sandbox keeps its size for life; change the size by creating another. Sandboxes shows a create with the common ones.

SettingDefault
Template: templatebase
CPUs: vcputhe template's defaults.vcpu (1 for base)
Memory: memory_mibthe template's defaults.memory_mib (512 MiB for base)
Disk: disk_gibthe template's (4 GiB for base)
Lifetime: timeout_s300 s
At the timeout: on_idlestop
Forkable: forkablefalse
Fork count: count1
Chrome reset on restore and fork: clone_resetthe node's: full on the beta node (per field)
Egress: egress.modepublic
API grant: api.scopesnone: code inside can call nothing (per field)
Port URL lifetime: ttl_s600 s
Command timeout: timeout_ms30,000 ms; none in the background (per field)
Working directory: cwd/workspace
Run as: useruser
Background: backgroundfalse
Code language: languagepython

Size and template

Template

What the sandbox starts with: its disk, its tools and its default size. run_code needs code-interpreter. Ignored when snapshot is set.

  • Field: template on create
  • Default: base
  • Values: a template name (base, code-interpreter, agent) or a tpl_ ID, from GET /v1/sandboxes/templates
  • Invalid value: 400 invalid_request
  • Guide: Templates
json
{"template": "code-interpreter"}
bash
b3os sandbox create --template code-interpreter

CPUs

Virtual CPUs. The template's default size comes from a pool of microVMs started ahead of time; any other size is restored on demand, which is slower, and the first create at a new size also builds a snapshot for it.

json
{"template": "base", "vcpu": 2}
bash
b3os sandbox create --vcpu 2

Memory

Memory, rounded up to 128 MiB or the next multiple of 256 MiB: a request for 600 runs with 768. The sandbox's memory_mib says what it got, and memory bills at that size.

  • Field: memory_mib on create
  • Default: the template's defaults.memory_mib (512 MiB for base)
  • Values: 128 MiB or more; at most your plan's sandboxes.memory_max (4,096 MiB in the beta)
  • Invalid value: 400 invalid_request, 422 limit_exceeded
json
{"template": "base", "memory_mib": 2048}
bash
b3os sandbox create --memory-mib 2048

Disk

The sandbox's disk size.

  • Field: disk_gib on create
  • Default: the template's (4 GiB for base)
  • Values: 1 GiB or more; at most the template's own disk, since disks do not grow in the beta
  • Invalid value: 400 invalid_request, 422 limit_exceeded
json
{"template": "base", "disk_gib": 4}
bash
b3os sandbox create --disk-gib 4

Lifetime

Lifetime

Seconds the sandbox runs from creation. A forgotten sandbox bills until then, so keep it short and extend it while you work: POST …/timeout on the sandbox sets a new lifetime from now, within the same bounds.

json
{"template": "base", "timeout_s": 900}
bash
b3os sandbox create --timeout-s 900

At the timeout

What happens at expires_at. stop destroys the sandbox. pause keeps it, so a resume after extending the timeout continues where it was; a paused sandbox is kept for an hour. It acts at expires_at, not when the sandbox is idle, so the SDKs and CLI 0.1.3 call it on_timeout.

json
{"template": "base", "on_idle": "pause"}
bash
b3os sandbox create --on-timeout pause

Forkable

Tracks the memory the sandbox changes, so it can be forked into up to 10 children. Forkable sandboxes come from a smaller pool, so set it only when you will fork.

json
{"template": "base", "forkable": true}

Fork count

How many children one fork call makes, each starting where the source was.

json
{"count": 4}

Chrome reset on restore and fork

What happens to the browser template's Chrome in a sandbox restored from your snapshot (a create with snapshot) or forked. full replaces its renderers and network service when the sandbox starts, so Math.random, crypto.getRandomValues and WebSocket keys are fresh, and closes the tabs that were open at the snapshot. none keeps Chrome as the snapshot had it, its random state shared with the source. A create from a template ignores it, and it covers no other process. The browser template is not on the beta yet; where the node's image of it predates the reset, full is refused with 409 guest_outdated.

json
{"count": 2, "clone_reset": "none"}

Network and access

Egress

Where the sandbox's traffic may go. public reaches any public address, allowlist only the hosts in egress.allow, and deny nothing. Private, loopback and metadata addresses are refused under every mode. A caller outside the sandbox can change it later; code inside cannot.

json
{"template": "base", "egress": {"mode": "allowlist", "allow": ["github.com", "*.githubusercontent.com"]}}

API grant

What code inside the sandbox may call on B3OS at http://127.0.0.1:7700, with no key: a subset of your own scopes, and an optional spend cap. With infer:run the environment also points the OpenAI and Anthropic SDKs at the node's models.

  • Field: api.scopes and api.spend_cap_usd on create
  • Default: none: code inside can call nothing (api.scopes), the creating key's own cap (api.spend_cap_usd)
  • Values: scope names from Scopes, within your own (api.scopes); 0 USD or more (api.spend_cap_usd)
  • Invalid value: 400 invalid_request
  • Guide: Agents in sandboxes
json
{"template": "base", "api": {"scopes": ["vision:run", "infer:run"]}}
bash
b3os sandbox create --api-scope vision:run,infer:run

Port URL lifetime

How long a URL minted for a private port works. Public ports ignore it; their URL's token lasts 7 days.

json
{"ttl_s": 3600}
bash
b3os sandbox port-url sbx_01example 8080 --ttl-s 3600

Commands

Command timeout

Kills the command after this long.

  • Field: timeout_ms on exec and run code
  • Default: 30,000 ms; none in the background (exec), 30,000 ms (run code)
  • Values: 1 to 3,600,000 ms; an exec waits at most 60,000 ms unless its output is streamed or it runs in the background (exec); 1 to 60,000 ms (run code)
  • Invalid value: 400 invalid_request
json
{"cmd": "make test", "timeout_ms": 60000}
bash
b3os sandbox exec sbx_01example --timeout-ms 60000 -- make test

Working directory

Where the command runs.

  • Field: cwd on exec
  • Default: /workspace
  • Values: an absolute path inside the sandbox
  • Invalid value: 400 invalid_request
json
{"cmd": "ls", "cwd": "/tmp"}
bash
b3os sandbox exec sbx_01example --cwd /tmp -- ls

Run as

The user the command runs as. root can install system packages.

json
{"cmd": "apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y -o Dpkg::Options::=--force-confold ffmpeg", "user": "root"}
bash
b3os sandbox exec sbx_01example --root -- 'apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y -o Dpkg::Options::=--force-confold ffmpeg'

Background

Returns at once with the process ID; read the output from the logs stream.

json
{"cmd": "python3 -m http.server 8080", "background": true}
bash
b3os sandbox exec sbx_01example --background -- python3 -m http.server 8080

Code language

The kernel run_code sends the code to, in the code-interpreter template.

json
{"code": "1 + 1", "language": "javascript"}

Fixed in the beta

These work one way in the beta, and no request field changes them.

Paused sandboxes

Kept 1 hour. A sandbox paused by on_idle: pause is stopped an hour after it paused. Snapshots are kept 7 days.

The model variable

Set with infer:run. A sandbox whose grant includes infer:run gets B3OS_MODEL, the node's default model, beside OPENAI_BASE_URL and ANTHROPIC_BASE_URL pointing at the node. A value you set in env wins. The node sets the model, and no request field changes it.

Connections per sandbox

512 open, 64 DNS lookups. A sandbox may have 512 outbound connections open and 64 DNS queries in flight. More connections are refused; more queries are answered SERVFAIL at once.

Ask a question... ⌘I