Technical Overview
How Open Spanner receives, stores, and queries usage.
Open Spanner runs a Next.js control-plane UI in front of a private Go API. The
web process owns the public HTTP endpoint and proxies /v1 requests to the API
at runtime. The API stores metering data in SQLite or Postgres, exposes REST for
control-plane and SDK operations, and exposes gRPC for trusted backend usage
ingestion.
Queued work is handled by separate worker binaries:
- The usage worker drains the transactional usage outbox into downstream queues.
- The export worker claims queued CSV export jobs and writes export artifacts.
- The alert worker claims alert evaluation jobs and delivers webhook notifications.
- The entitlement worker claims quota state jobs and records entitlement state, events, and period snapshots.
Request Flow
- A service sends an API key with the request.
- The HTTP or gRPC layer authenticates the key or dashboard cookie.
- The authorization layer checks scopes and meter restrictions.
- Metering handlers validate request shape and pass commands into the application layer.
- The domain layer applies meter, usage, plan, entitlement, alert, export, and retention rules.
- A storage adapter writes to or reads from SQLite or Postgres.
- Usage writes commit an outbox record atomically; the usage worker then queues matching alert and entitlement work.
Storage Model
Meters and plans are configuration records. Usage events are immutable facts with idempotency keys. Usage queries aggregate retained events at request time using SQL.
Entitlement progress uses per-period counters that are updated as accepted usage is recorded, so quota checks do not need to scan raw events on every request. The entitlement worker then evaluates queued subject and meter pairs to store the latest quota state, state transition events, and period snapshots for dashboard and API reads.
Postgres and SQLite share the same domain behavior but use database-specific SQL where it matters for performance.
API Surfaces
- Dashboard routes use cookie sessions.
- Service routes accept scoped API keys.
- SDKs expose meters, usage operations, direct exports, and entitlement checks.
- gRPC stream ingestion accepts API keys from backend services.
- Generated OpenAPI artifacts document the REST API for SDK and reference workflows.
Process Topology
For production, treat the API and workers as separate processes that share one Postgres database:
| Process | Main work |
|---|---|
| Web | Next.js dashboard and public REST proxy. |
| API | REST, gRPC ingestion, auth, migrations, metrics, and readiness. |
| Usage worker | Transactional usage outbox fanout. |
| Export worker | CSV export jobs and artifact writes. |
| Alert worker | Alert rule evaluation and webhook delivery. |
| Entitlement worker | Quota state refresh, entitlement events, and period snapshots. |
SQLite is best for local demos or single-node trials. Postgres is the recommended production store because it supports durable backups, multiple API instances, multiple workers, and row-level job claiming.