Architecture

One binary. One database file. No external services.

Stockyard uses embedded SQLite instead of Postgres, Redis, or any external database. This page explains why, where the tradeoffs are, and what the real numbers look like.

Why SQLite for a proxy

An LLM proxy is I/O-bound on network calls to providers, not on database operations. The slowest thing Stockyard does is wait for OpenAI or Anthropic to respond — that's 500ms to 5 seconds. Writing a trace to SQLite takes microseconds. The database is never the bottleneck.

This means Stockyard can use an embedded database and gain enormous operational simplicity without giving up meaningful performance. No connection pooling, no schema migrations across network boundaries, no database server to monitor, no credentials to rotate for internal services.

# Proxy overhead: time Stockyard adds on top of provider latency 76 middleware modules executing: ~400 nanoseconds Full proxy round-trip overhead: ~200 milliseconds (includes TLS, HTTP parsing, middleware chain, trace write) # SQLite operations Trace write (WAL mode): <1ms Audit ledger append: <1ms Cache lookup: <1ms Config/alias read: <0.1ms

Full benchmarks at /benchmarks/ with methodology and reproducible test harness.

How it's configured

WAL mode is enabled by default. This gives concurrent reads while writes happen, which matters when the dashboard is querying traces while the proxy is writing new ones.

Integer cents for all money values. No floating-point arithmetic, no rounding drift. $1.42 is stored as 142.

AES-256-GCM encryption for provider API keys at rest. Keys are decrypted in memory at startup and never written to logs or API responses.

Pure-Go driver via modernc.org/sqlite. No CGO, no C compiler needed, no dynamic linking. The SQLite engine is compiled into the Go binary. This is what makes the single static binary possible.

SQLite is a single-writer database. If you need multiple Stockyard instances writing to the same database simultaneously, SQLite won't do that. This means Stockyard scales vertically, not horizontally at the database layer.

For most teams running an LLM proxy, this isn't a constraint. A single Stockyard instance handles thousands of concurrent proxy requests because the bottleneck is provider response time, not database writes. The write load is one trace row per request — SQLite handles tens of thousands of those per second.

If you reach the point where a single instance can't keep up, you're doing enough volume that running two instances with separate databases (or switching to a shared Postgres backend) is a reasonable next step. Stockyard isn't there yet, and neither are most teams evaluating this.

The operational upside

Backup is cp. Copy the .db file and you have a complete backup of all traces, config, aliases, audit ledger, and cached responses.

Deploys are trivial. Copy one binary, point at the data directory, start. No migration runner, no connection string, no "is the database up?" healthcheck.

Debugging is sqlite3. Open the database with any SQLite client and query it directly. No ORM translation layer, no remote connection needed.

Attack surface is minimal. No database port to expose, no credentials to manage for internal services, no network path between proxy and database to secure.

Simple until you need complex.

Start with one binary and one file. If you outgrow it, you'll know — and you'll have the traces to prove it.

Install Stockyard
Benchmarks → Architecture → Why Go + SQLite →
Explore: Proxy-only mode · Self-hosted proxy · OpenAI-compatible
Stockyard also makes 150 focused self-hosted tools — browse the catalog or get everything for $29/mo.