How OpenSandbox Manages the Full Sandbox Lifecycle: Creation, Pausing, Resuming, and Deletion
OpenSandbox manages sandbox lifecycles through a FastAPI server that translates HTTP requests into gRPC calls to an execd daemon, which controls Kubernetes containers through distinct phases—creation, pause, resume, and deletion—while maintaining state in an in-memory store.
OpenSandbox treats each sandbox as a short-lived, isolated execution environment running inside a Kubernetes cluster. The platform exposes a comprehensive lifecycle management API through its Python SDK and underlying HTTP endpoints. This article examines how OpenSandbox manages the full sandbox lifecycle from initial creation through final termination, based on the actual source code implementation in the alibaba/OpenSandbox repository.
The Four Core Lifecycle Operations
OpenSandbox exposes four primary HTTP endpoints that drive the sandbox state machine. Each operation returns specific status codes and transitions the sandbox through defined states.
Sandbox Creation initiates via POST /sandboxes, implemented in sdks/sandbox/python/src/opensandbox/api/lifecycle/api/sandboxes/post_sandboxes.py. This endpoint accepts a 202 Accepted response and transitions the sandbox from Pending to Running once the container initializes.
Pausing Execution occurs through POST /sandboxes/{sandbox_id}/pause, defined in post_sandboxes_sandbox_id_pause.py. The execd daemon sends a SIGSTOP-like signal to the container’s main process, preserving the filesystem and network namespace while setting the state to Paused.
Resuming Execution uses POST /sandboxes/{sandbox_id}/resume from post_sandboxes_sandbox_id_resume.py. This sends a SIGCONT signal to continue execution from the exact paused state, returning the sandbox to Running status with a 202 Accepted response.
Deletion and Termination happen via DELETE /sandboxes/{sandbox_id} in delete_sandboxes_sandbox_id.py. This triggers a graceful shutdown sequence (SIGTERM → SIGKILL) followed by pod deletion, returning 204 No Content and moving the state through Stopping to Terminated.
Architectural Flow: From API to Container
The lifecycle implementation spans three architectural layers that coordinate container operations.
FastAPI Server Layer receives HTTP requests at the endpoints defined in server/ and validates the OPEN-SANDBOX-API-KEY header. The server auto-generates these routes from the OpenAPI specification and forwards validated requests to the backend.
Execd Daemon Layer (components/execd/pkg/...) implements the actual container control logic written in Go. The FastAPI server translates HTTP requests into gRPC or HTTP calls to this daemon. Execd spawns Kubernetes pods (or lightweight containers) to run sandbox code and maintains an in-memory store tracking each SandboxStatus object.
Ingress Provider Layer (components/ingress/pkg/sandbox/provider.go) creates a per-sandbox reverse proxy enabling external callers to reach sandbox endpoints via HTTP or SSH throughout the lifecycle.
When processing lifecycle requests, execd handles process signals directly. Pause operations freeze execution without releasing resources, while deletion initiates a cascading resource cleanup that removes the pod and associated network policies.
State Machine and Status Tracking
OpenSandbox implements a strict state machine defined in sdks/sandbox/python/src/opensandbox/api/lifecycle/models/sandbox_status.py. The valid state transitions follow this progression:
Pending → Running → (Paused ↔ Running) → Stopping → Terminated
- Pending: Container creation initiated but pod not yet ready
- Running: Active execution with all resources allocated
- Paused: Execution frozen, resources retained, ingress routes maintained
- Stopping: Termination signal sent, cleanup in progress
- Terminated: All resources released, sandbox ID invalid for further operations
The execd daemon updates this status object atomically after each lifecycle operation, ensuring the Python SDK receives consistent state information when calling SandboxSync.get_info().
Code Examples
Creating a New Sandbox
The Python SDK wraps the creation endpoint in post_sandboxes.sync, constructing the HTTP request via httpx and parsing the JSON response into a Sandbox object.
from opensandbox import SandboxSync
from opensandbox.models.sandboxes import SandboxImageSpec
image_spec = SandboxImageSpec(image="myrepo/my-sandbox:latest")
sandbox = SandboxSync.create(image=image_spec)
print(f"Sandbox created – ID: {sandbox.id}")
print(f"Current state: {sandbox.status.state}") # Pending → Running
Underlying call: opensandbox.api.lifecycle.api.sandboxes.post_sandboxes.sync → POST /sandboxes (202 Accepted)
Pausing and Resuming Execution
Pause and resume operations use synchronous methods that block until the execd daemon confirms the signal delivery.
sandbox_id = sandbox.id
# Pause the container
SandboxSync.pause(sandbox_id)
info = SandboxSync.get_info(sandbox_id)
assert info.status.state == "Paused"
# Resume execution from saved state
SandboxSync.resume(sandbox_id)
info = SandboxSync.get_info(sandbox_id)
assert info.status.state == "Running"
Underlying calls: post_sandboxes_sandbox_id_pause.sync and post_sandboxes_sandbox_id_resume.sync → POST /sandboxes/{sandbox_id}/pause and /sandboxes/{sandbox_id}/resume
Deleting a Sandbox
Deletion returns immediately with 204 No Content, but the actual termination happens asynchronously. Poll the status endpoint to confirm completion.
SandboxSync.delete(sandbox_id)
# Poll until resources are fully released
while True:
info = SandboxSync.get_info(sandbox_id)
if info.status.state == "Terminated":
break
Underlying call: delete_sandboxes_sandbox_id.sync → DELETE /sandboxes/{sandbox_id} (204 No Content)
Key Implementation Files
The lifecycle management spans multiple components across the repository:
sdks/sandbox/python/src/opensandbox/api/lifecycle/api/sandboxes/post_sandboxes.py– Python SDK implementation for sandbox creationsdks/sandbox/python/src/opensandbox/api/lifecycle/api/sandboxes/post_sandboxes_sandbox_id_pause.py– SDK pause operation wrappersdks/sandbox/python/src/opensandbox/api/lifecycle/api/sandboxes/post_sandboxes_sandbox_id_resume.py– SDK resume operation wrappersdks/sandbox/python/src/opensandbox/api/lifecycle/api/sandboxes/delete_sandboxes_sandbox_id.py– SDK deletion implementationsdks/sandbox/python/src/opensandbox/api/lifecycle/models/sandbox_status.py– State machine definitions andSandboxStatusmodelcomponents/execd/pkg/...– Go daemon handling container runtime operationsserver/...– FastAPI HTTP endpoint definitions auto-generated from OpenAPI speccomponents/ingress/pkg/sandbox/provider.go– Per-sandbox network routing and ingress management
Summary
- OpenSandbox manages sandbox lifecycles through a FastAPI server that proxies requests to the execd Go daemon, which directly controls Kubernetes containers.
- The lifecycle supports four core operations: create (202 Accepted), pause (SIGSTOP), resume (SIGCONT), and delete (SIGTERM → SIGKILL, 204 No Content).
- Sandboxes transition through a strict state machine: Pending → Running → (Paused ↔ Running) → Stopping → Terminated.
- The Python SDK in
sdks/sandbox/python/wraps HTTP endpoints with synchronous (SandboxSync) and asynchronous (SandboxAsync) methods. - Process signals preserve filesystem and network state during pauses, while deletion triggers cascading resource cleanup including pod termination and ingress removal.
Frequently Asked Questions
How does OpenSandbox handle sandbox pausing at the container level?
The execd daemon sends a SIGSTOP-like signal to the container's main process, freezing execution without releasing filesystem or network resources. This differs from deletion by maintaining the pod infrastructure while preventing CPU scheduling, allowing instant resumption via SIGCONT without cold-start penalties.
What is the difference between sandbox expiration renewal and resuming?
Resuming (POST /sandboxes/{id}/resume) restores execution to a paused sandbox, changing the state from Paused to Running. Expiration renewal (POST /sandboxes/{id}/renew-expiration) extends the time-to-live (TTL) timer for a running sandbox without changing its execution state, preventing automatic termination while maintaining active execution.
Which HTTP status codes indicate successful lifecycle operations?
Creation, pause, and resume operations return 202 Accepted to indicate the request was accepted but final state confirmation requires polling. Deletion returns 204 No Content indicating immediate success with no response body. The SDK methods raise errors.UnexpectedStatus for any undocumented status codes outside the expected success or error ranges.
How does the execd daemon track sandbox state transitions?
Execd maintains an in-memory store of SandboxStatus objects that update atomically after each container operation. When the Python SDK calls SandboxSync.get_info(), it retrieves the current state from this store via the FastAPI server, ensuring consistent visibility of transitions between Pending, Running, Paused, and Terminated states.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →