Sub-second consensus on Cloudflare Durable Objects
How a per-game “consensus room” turns a stream of independent reports into one confirmed event, fast enough to trade on.
The hard part of a consensus feed isn't the consensus — it's doing it fast, per game, at the moment a thousand fans react at once. Here's the architecture we landed on.
One Durable Object per live game
Each eligible live game gets its own Cloudflare Durable Object — a single-threaded, strongly-consistent "consensus room." Reports for that game route to that one object, so the tally lives in one place with no cross-region coordination. When the game ends, the object spins down. This keeps the hot path tiny: a report is a message to one actor that already holds all the state it needs.
The hot path
A report arrives with a team, an event, a client timestamp, and the reporter's identity. The room:
- validates the reporter is checked in and inside the venue geofence;
- adds their reputation-weighted vote to the live tally for that moment;
- checks whether weighted agreement has cleared the threshold within the window;
- if so, emits a
confirmedevent and computes the speed-tiered payout split.
All in memory, in one object, in well under a second.
Provisional vs confirmed
Some buyers want raw speed; some want certainty. So the room can emit a provisional event off the first credible report — tagged, never presented as final — and follow it with a confirmed (or a correction) once consensus resolves. Subscribers choose their tier; the schema is identical either way.
Fan-out without backpressure
Confirmed events leave the room and hit a fan-out layer: WebSocket subscribers get them on open sockets; webhook subscribers get them via a queue with retries and replay. Slow consumers can't slow the room — delivery is decoupled from consensus.
Determinism is a feature
The same reports in the same order always produce the same confirmed event. That's what lets the historical archive match the live feed exactly — your backtest and your production path see byte-identical data. It's a structural guarantee, not a discipline.
Why this shape
Durable Objects give us per-game serialization for free, at the edge, close to where reports originate. No global lock, no shared queue contention, no race to write the same tally. The unit of consistency is exactly the unit of the problem: one game.