Case study: Electronic stock exchange
Design a deterministic low-latency order matching engine with price-time priority, sequenced command logs, and O(1) order book operations.
35 min9 steps
By the end you can
- Estimate peak order/cancel message rate and prove that the entire active order book fits in CPU cache and RAM
- Design an in-memory limit order book using price levels, doubly-linked FIFO queues, and an orderId hash map for O(1) cancel and match
- Use a partitioned sequencer log and single-threaded deterministic matching to guarantee strict price-time priority without ordering violations
- Predict how the exchange handles hot earnings-release symbols, market-open bursts, and hot-standby failover
Pin down exchange fairness and determinism
Price-time priority
- Best price first; FIFO within price; deterministic replay
Order entry
- Integer ticks; clOrdId dedup; fills/cancels; no lost sequenced commands
Show that the entire order book fits in L3 cache and RAM
Messages/s
210k
5B / 23,400s; ~1M peak
Cancels/replacements
85-90%
Dominant operation
Resting order book
640 MB
10M / 64 B; ~80 KB/symbol average
Sequencer log/day
320 GB
5B / 64 B
Design the order gateway and market data protocols
POST /v1/orders; DELETE /v1/orders/{ordId}
- NewOrderSingle / cancel; risk-check, dedup, sequence
GET /v1/marketdata/{symbol}/book
- L1/L2; FIX/SBE/OUCH entry, ITCH data; integer priceTicks
Build an O(1) in-memory limit order book
Price levels
- Sorted bids/asks; FIFO doubly-linked order lists
orderId map
- O(1) unlink/cancel; append after locating level; match O(1) per filled node
Connect gateways, the sequencer log, and the matching engine
Place the steps of processing a new limit order in their exact architectural order.
- 1Single-threaded matching engine for that symbol partition consumes the command in sequence order and matches against the in-memory book
- 2Sequencer assigns a monotonic sequence number and appends the command to the symbol's ordered log partition
- 3Matching engine emits ExecutionReport fills and publishes updated L1/L2 market data to the cache and subscribers
- 4Order gateway verifies `clOrdId` idempotency and checks pre-trade risk limits (buying power, price collar)
Deep dive: price-time priority and deterministic state machines
One ordered loop/symbol
- Sequence 101 executes before 102; replicas replay identical commands
Scale across symbols
- Preallocated ring; no I/O in loop; concurrent same-symbol workers break fairness
Compare the alternatives
exchange-unordered-workers
- Overtaking/redelivery violates orderingViolated
exchange-sql-matching
- DB saturates; <70% goodput
Replicated input log
- Standby replays commands before takeover
Run the failure scenarios
Inject
hot-symbol: 80%
Observe
Reference preserves FIFO; >99% fixture goodput
Result
Unordered workers trigger orderingViolated
Inject
market-open-burst: 2x
Observe
Fixture reaches 6,000 rps
Result
In-memory path meets 200ms fixture deadline
Inject
md-cache-flush: t=1.5s
Observe
Market cache restarts
Result
Matching continues while reader cache refills
Wrap up and self-assess
Cancel-on-disconnect
- Sequence CancelAll; participant kill switch
Price protection
- Gateway collars; per-symbol circuit breakers
Answer this step to continue.