Single writer per table
Every event-bearing table has exactly one writer in steady state. The live ingestion path owns the block-by-block stream (fills, order statuses, book snapshots, liquidations); a dedicated polling process owns the protocol-emission tables (funding rates, mark prices, open interest); bridge events come from the same live path on a separate channel. There is no scenario where two services race to write the same row. This is enforced at deploy time — the stack refuses to ship a configuration that introduces a second writer.Idempotent ingest and recovery
Every batch carries a deterministic identifier so retries are free. Network blips, restarts, and recovery passes can repeat without producing duplicates. Combined with storage-layer dedup, the system guarantees:- A network blip during recovery produces zero duplicate rows.
- A re-run of a recovered window is a no-op.
- A killed recovery process can be restarted without manual cleanup.
Gap detection
At hour close, the pipeline records what was supposed to land — the block range, expected event count, and a content hash of the source. A continuous detector compares that record against what actually landed in the database, scoped by block range so events written near the hour boundary aren’t miscounted. When an actual gap is detected, recovery runs automatically against the live source files (recent gaps) or the long-tail archive (older gaps). Operators don’t intervene unless the gap predates the archive window, which is documented per-table.Continuous audit
Live ingested data is cross-checked continuously against the venue’s own records — hourly field-level checks on the live window, and a daily replay of the venue’s published archive against what we ingested in real time. Any divergence alerts the team before it can reach a customer query.Launch-verification harness
Before any major release, a separate harness re-runs offline and sliding-window checks covering historical block coverage, identity completeness, book aggregator drift, funding continuity, and freshness budgets. Every gate must pass to clear the release threshold.Honest limits
We’re explicit about where the guarantees stop:- Local source-file retention is a few hours per data type. Beyond that, recovery is from the long-tail archive, which itself only covers data types the venue archives publicly. Tables without an archive source start from a documented launch date.
- Upstream API rate limits can briefly stall the polling process during high-load periods; protocol-emission tables can be tens of seconds stale on affected polls. This is observable on the public status page and surfaces as a freshness alert if it exceeds the configured budget.
- External audit sources (third-party explorers, aggregators) have their own uptime; we treat their transient failures as retryable rather than blocking, so a third-party outage doesn’t reset our green streak.