worb architecture

← back

A single executable, a single SQLite file, zero external dependencies.

wandb Python client HTTP worb single Go binary file_stream GraphQL REST API Write-Ahead Log batch Store Dashboard go:embed File Store ~/.worb/files/ SQLite ~/.worb/worb.db

Layers

Everything runs in one process. There is no message queue, no cache layer, no container orchestration. The WAL file and the SQLite database are the only state on disk.

The WAL

The wandb client streams metrics over HTTP at high frequency. Writing each row directly to SQLite would serialize every request behind a database lock, so worb interposes an application-level write-ahead log.

Incoming data is appended to a single WAL file on disk (~/.worb/wal.jsonl). A background goroutine wakes up every 500 ms (or when a batch reaches 50,000 items), reads a chunk from the WAL, and flushes it to SQLite in a single transaction. The WAL file is compacted once it exceeds 1 GB.

This design means the HTTP handler only does an append() to a file and returns. SQLite writes happen in the background, batched and ordered, with no contention on the ingestion path.

HOT PATH wandb.log() file_stream WAL append 200 OK BACKGROUND WAL reader batch 50k rows INSERT ... COMMIT

Storage

All experiment data lives in a single SQLite database file at ~/.worb/worb.db. Backups are a file copy. There is no export tool, no dump command, no migration to run. You can also point worb at a Turso database for hosted/replicated SQLite, or DuckDB if you prefer columnar storage.

The schema is designed around the wandb data model: projects contain runs, runs contain history rows. History is stored as one row per metric per step (run_id, step, key, value) rather than one JSON blob per step. This makes per-key range queries fast and avoids parsing large JSON objects on read.

Uploaded files (model checkpoints, artifacts) go to a flat directory on disk (~/.worb/files/) with metadata tracked in the files table. The file store is a simple content-addressed layout, no object storage dependency.

~/.worb/ worb.db SQLite — all metadata + metrics wal.jsonl write-ahead log (transient) wal.pos WAL read cursor position files/ uploaded artifacts and models

Compatibility

worb implements enough of the wandb server API that the standard wandb Python client works without patches. You set WANDB_BASE_URL to your worb instance, and wandb.init(), wandb.log(), and wandb.finish() work as expected.

The GraphQL endpoint handles the handshake and metadata queries the client makes on init and finish. The file_stream endpoint accepts the chunked metric uploads. A built-in GraphQL playground is available at /playground for exploration.

The SQL console in the dashboard lets you query the underlying SQLite database directly, which is useful for ad-hoc analysis that goes beyond what the charts offer.

Your Python code wandb.init() wandb.log() wandb.finish() WANDB_BASE_URL=... worb /graphql /file_stream /api/* + /playground Dashboard charts histograms SQL console run logs
GitHub