Skip to content

Backend Deep Dive

Application lifecycle

main.py initializes SQLite, builds AppState, attaches it to app.state.sandbox, starts periodic cleanup, and stops cleanup during lifespan shutdown. The API router depends on this shared state for settings, repositories, runtimes, and exporters.

Route families

Family Operations
Health /healthz, /readyz, /v1/backends
Sessions create, list, get, heartbeat, stop, delete
Execution create exec, get exec, stdout/stderr offset reads
Files read/write/list/delete, archive upload/download
Artifacts sync and list exports
Snapshots create/list/get/delete
Maintenance /v1/gc

Session creation

The route validates a snapshot’s existence and workspace ownership, chooses microsandbox when restoring, creates a metadata record, creates a scratch workspace, restores an optional archive, starts the runtime, then stores runtime paths and sandbox name. This ordering gives the API a durable record even while runtime setup is in progress.

Concurrency and cleanup

Handlers are async, but SQLite repository calls and local filesystem operations are synchronous. Runtime command execution is awaited. Cleanup periodically expires sessions and removes execution logs. A production deployment should consider executor isolation for blocking filesystem/database work and explicit per-session concurrency limits.

Error conventions

Missing resources return 404, invalid state transitions return 409, path escapes return 400, and unavailable readiness returns 503. Runtime failures become failed execution records rather than uncaught process crashes.