Skip to content

Exhibits

Three architecture comparisons on the portfolio front door — each one a decision, made observable. The governing rule: an architecture choice is only shown when its rejected alternative stands right next to it, and a viewer can see the difference, not just read a claim about it. See decisions/ for the full ADR index.

Exhibit 01 is live now. Exhibits 02 and 03 are still being built — the front door shows this honestly (an "in build" notice, never a placeholder number) via /api/status, and so does this page.

Exhibit 01 — Freshness vs cost (batch vs streaming) — live

The decision: ADR-0006 — scheduled micro-batch is the recommended production default; streaming is built anyway, as the priced alternative, so the tradeoff is a real number instead of a claim.

What's running: one real source — Wikimedia's public EventStreams feed — ingested twice in parallel. A poller connects on a schedule, captures a short window, disconnects, and bulk-inserts (the batch path). A resident-but-idle streamer consumes the same feed continuously through Redis Streams, backed by in-process run windows rather than spinning up containers on a public trigger.

What you can do: click Run. Both paths land rows in the same fact table; the page polls /api/exhibits/batch-streaming/metrics and draws freshness for each path as it happens — the batch side's gap between capture windows, and the streaming side's near-zero lag, side by side.

Exhibit 02 — Coupling vs resilience (sync vs async) — in build

The plan: ADR-0009's bounded-run pattern, reused for a different tradeoff — a controllable Hacker News hydration call will feed two identical consumers, one calling it synchronously, one reading through a queue boundary.

What it will let you do: inject a fault (slow or stalled upstream) and watch the two paths diverge — the synchronous path degrading with its upstream in real time, the queue-backed path absorbing the hit and draining once the fault clears, auto-healing after 60 seconds regardless of further clicks. Not live yet — CP12 builds this.

Exhibit 03 — Engine choice (Postgres vs DuckDB) — in build

The plan: the same accumulated fact table, queried two ways once enough history has accumulated — a row-store OLTP engine already running the rest of the lab, and a columnar engine over a Parquet snapshot of the same data. Planned as a written comparison rather than a live toggle: engine tuning is a weaker architect signal than the two exhibits above, so it will get a number, not a button. Not live yet — CP13 builds this, and needs weeks of accumulated data first.

Why these three, and why live

Most architecture portfolios are claims with nothing underneath; most data-engineering portfolios are running evidence with no articulated thinking on top. The exhibits exist to close that loop: a written decision, an implementation of both sides of it, and a number a stranger can trigger and watch. Every exhibit is rate-limited and capped server-side — see ADR-0010 — because a public, unauthenticated trigger is itself an architecture decision worth being explicit about.