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.syncPOST /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.syncPOST /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.syncDELETE /sandboxes/{sandbox_id} (204 No Content)

Key Implementation Files

The lifecycle management spans multiple components across the repository:

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →