QuantumLane.

Architecture

QuantumLane is a single-box data platform that demonstrates production patterns at the smallest scale that still requires real engineering. The full architecture document with ADRs lives in the repo; what follows is the summary.

Principles

  1. Boring tech that runs forever beats novel tech that runs for a month.
  2. Observability is a first-class feature, not an afterthought.
  3. Document the trade-off, not the tool.
  4. Schema is contract. Forward-only migrations, never ALTER TABLE in psql.
  5. Local dev = production in a smaller box.
  6. Model by access pattern, not by volume. The right store and grain follow from how data is read, not how much there is.
  7. Cost discipline is part of the design.

Stack

LayerChoiceWhy
OrchestrationDagsterAsset-centric model; lighter than Airflow at single-box scale.
DatabasePostgreSQL 16 + PostGISOne store at this scale; best-in-class geospatial.
Object storageAmazon S3Cold-tier Parquet archive with Hive-style partitioned keys.
APIFastAPI + Pydantic v2Async, auto OpenAPI, modern validation.
WebsitePlain HTML + Tailwind CDNA few pages, monthly updates โ€” no build system needed.
Reverse proxyCaddyAutomatic TLS, dead-simple config.
HostHetzner CPX21Far cheaper than AWS for the same patterns.

Hot / cold split

Real-time data lands in a hot tier (PostgreSQL/PostGIS) that serves live API reads and near-real-time queries. A daily job archives it to a cold tier โ€” Parquet on S3, partitioned by UTC day with Hive-style keys โ€” for historical analytics. The two paths are deliberately separate: live operational queries and historical aggregation have different access patterns, so they get different stores rather than one general-purpose table doing both jobs.

Both ingestion and archival are written to stay within memory on a small box. Large static GTFS files (e.g. stop_times, ~4M rows) stream row-by-row into COPY from the open archive; the Parquet export reads through a server-side cursor into a held-open writer rather than materializing the result set.

Delay & reliability

Three features share the word "delay" but are modelled separately, each by its access pattern:

The mechanism underneath is a stop-level overwrite: one row per (trip_id, stop_sequence), upserted as predictions arrive and finalized on arrival. A large volume of superseded predictions collapses to one durable row per stop-event, which then feeds both the live gauge and the historical aggregate from a single source.

MCP server

QuantumLane runs a public Model Context Protocol server, so LLM clients โ€” Claude and ChatGPT โ€” can answer live transit questions in plain English: vehicles on a route (with rider-language โ†’ route_id resolution), nearest stops via PostGIS KNN, and route lookup. It deliberately wraps the deployed public API rather than the database โ€” no separate data path, no DB credentials in the MCP layer, one source of truth.

Guardrails are right-sized for a small shared box: a per-IP rate limit and a route-catalog cache whose TTL matches the catalog's actual change cadence (the daily static-GTFS reload) โ€” not auth or quotas, which the access pattern doesn't justify. Today's tools are live and spatial; the analytical tools ("how reliable is the 504 usually") arrive with the OLAP layer below. How to connect โ†’

What's in v0.4

Planned

Deliberately not here

Cost

Cost discipline is treated as a design constraint, not an afterthought: a single small Hetzner box, an S3 cold tier sized to what the analytics actually need, and free-tier DNS and CI. The architecture is chosen so the running cost stays low and predictable โ€” the cold-tier read path in particular is designed around egress, which is why historical bulk access is handled differently from the always-free hot-tier live queries.