Auto-resume is for long-lived workspaces, preview servers, and per-user
sandboxes that should not run constantly. Configure the sandbox to pause on
timeout, then set auto_resume=True so public HTTP/WebSocket traffic can wake
it before the request is proxied.
Choose one control plane for the create call: Python SDK, CLI, or raw HTTP.
All three snippets configure the same timeout and auto-resume behavior.
from nullspace import Sandbox
sandbox = Sandbox.create(
template="base",
timeout=600,
on_timeout="pause",
auto_resume=True,
)
auto_resume=True requires pause/hibernate timeout behavior. A sandbox with
destroy-on-timeout cannot auto-resume because there is no paused state to
restore.
Wake from public traffic
server = sandbox.commands.run(
"python3 -m http.server 8080 --bind 0.0.0.0",
shell=True,
cwd="/workspace",
background=True,
)
url = sandbox.get_url(8080)
print(url)
After the sandbox times out and pauses, an inbound request to the signed HTTP
URL or signed WebSocket URL asks the control plane to resume the paused
sandbox. When the resume completes within the bounded wait window, the edge
forwards the original request to the resumed execution.
If auto-resume is disabled or the resume cannot complete in time, the public
URL returns 503 Service Unavailable with Retry-After: 5. The JSON body
includes a stable code, retryable, and suggested_action. Disabled policy
responses use sandbox_paused_auto_resume_disabled with retryable: false.
Timeout or control-plane availability failures are retryable and can be retried
after the Retry-After delay.
Wake from SDK calls
from nullspace import Sandbox
sandbox = Sandbox.connect("sb_...")
result = sandbox.commands.run("echo resumed", shell=True)
print(result.stdout)
Sandbox.connect(id) is an explicit reconnect operation. If id points at a
paused sandbox alias, connect() resumes its snapshot and returns a running
sandbox handle.
Use Sandbox.get_info_by_id(id) when you need a read-only status check that
does not wake a paused sandbox.
info = Sandbox.get_info_by_id("sb_...")
print(info.status, info.snapshot_id)
Paused aliases and new IDs
Resume creates a new running sandbox execution. The original paused sandbox ID
is kept as an alias so reconnect and traffic-triggered wakeups can find the
latest resumed target. Code that persists sandbox IDs should update its stored
ID after connect() or resume returns a new handle.
original_id = sandbox.id
snapshot = sandbox.pause()
resumed = Sandbox.connect(original_id)
print(original_id, resumed.id)
Shared volume attachments are remounted when a sandbox resumes. VM memory and
mutable rootfs state still depend on snapshot compatibility with the runtime
host and kernel.
Common patterns
| Pattern | Recommended configuration |
|---|
| Preview server that should wake on a browser hit | on_timeout="pause", auto_resume=True |
| Per-user workspace stored by sandbox ID | Store the latest sandbox.id after connect() |
| Background agent task with explicit scheduler | Use Sandbox.connect(id) before each task |
| Disposable CI-style run | Keep default destroy-on-timeout behavior |