# How OpenSandbox Manages the Full Sandbox Lifecycle: Creation, Pausing, Resuming, and Deletion

> Discover how OpenSandbox manages sandbox lifecycles, from creation to deletion. Learn how it controls Kubernetes containers through distinct phases with FastAPI and gRPC.

- Repository: [Alibaba/OpenSandbox](https://github.com/alibaba/OpenSandbox)
- Tags: internals
- Published: 2026-03-08

---

**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`](https://github.com/alibaba/OpenSandbox/blob/main/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`](https://github.com/alibaba/OpenSandbox/blob/main/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`](https://github.com/alibaba/OpenSandbox/blob/main/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`](https://github.com/alibaba/OpenSandbox/blob/main/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`](https://github.com/alibaba/OpenSandbox/blob/main/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`](https://github.com/alibaba/OpenSandbox/blob/main/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.

```python
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.

```python
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.

```python
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`](https://github.com/alibaba/OpenSandbox/blob/main/sdks/sandbox/python/src/opensandbox/api/lifecycle/api/sandboxes/post_sandboxes.py)** – Python SDK implementation for sandbox creation
- **[`sdks/sandbox/python/src/opensandbox/api/lifecycle/api/sandboxes/post_sandboxes_sandbox_id_pause.py`](https://github.com/alibaba/OpenSandbox/blob/main/sdks/sandbox/python/src/opensandbox/api/lifecycle/api/sandboxes/post_sandboxes_sandbox_id_pause.py)** – SDK pause operation wrapper
- **[`sdks/sandbox/python/src/opensandbox/api/lifecycle/api/sandboxes/post_sandboxes_sandbox_id_resume.py`](https://github.com/alibaba/OpenSandbox/blob/main/sdks/sandbox/python/src/opensandbox/api/lifecycle/api/sandboxes/post_sandboxes_sandbox_id_resume.py)** – SDK resume operation wrapper  
- **[`sdks/sandbox/python/src/opensandbox/api/lifecycle/api/sandboxes/delete_sandboxes_sandbox_id.py`](https://github.com/alibaba/OpenSandbox/blob/main/sdks/sandbox/python/src/opensandbox/api/lifecycle/api/sandboxes/delete_sandboxes_sandbox_id.py)** – SDK deletion implementation
- **[`sdks/sandbox/python/src/opensandbox/api/lifecycle/models/sandbox_status.py`](https://github.com/alibaba/OpenSandbox/blob/main/sdks/sandbox/python/src/opensandbox/api/lifecycle/models/sandbox_status.py)** – State machine definitions and `SandboxStatus` model
- **`components/execd/pkg/...`** – Go daemon handling container runtime operations
- **`server/...`** – FastAPI HTTP endpoint definitions auto-generated from OpenAPI spec
- **[`components/ingress/pkg/sandbox/provider.go`](https://github.com/alibaba/OpenSandbox/blob/main/components/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.