AI System Design
← All chapters
Chapter 28 7 min read

Stock Exchange

An electronic exchange matches buy and sell orders with microsecond-level, highly predictable latency while guaranteeing fairness and a perfectly deterministic record. The design keeps the critical path on a single server, sequences every event, runs a matching engine over in-memory order books, and rebuilds state from an event log for high availability.

Architecture at a glance
  1. Broker / client gateway
  2. Order manager (risk check, wallet)
  3. Sequencer (inbound)
  4. Matching engine (order books)
  5. Sequencer (outbound)
  6. Order manager / reporter / market data publisher

Stock exchange 101

An exchange matches buyers and sellers efficiently. Retail investors reach it through brokers, while institutional clients such as funds trade in large volumes and often split orders to avoid moving the price. A limit order buys or sells at a fixed price or better and may wait in the book; a market order executes immediately at the best available price and gives up price control for speed.

Market data comes in levels. L1 shows the best bid and best ask with quantities. L2 adds more price levels of depth. L3 shows every individual order at each level. Candlestick charts summarise prices over an interval with open, close, high and low. Many brokers and exchanges speak FIX, a long-established, vendor-neutral protocol for exchanging securities transaction messages.

Requirements and estimation

Our exchange trades 100 symbols and handles billions of orders per day. Clients can place and cancel limit orders, receive real-time executions and market data, and must pass risk checks, for example a cap on how many shares of one symbol a user can trade per day. Each order must have funds locked in a wallet before submission, so buyers cannot spend the same money twice. Requirements emphasise availability, fault tolerance, and above all low and predictable latency, measured at the 99th percentile, because tail latency is what traders actually feel.

Assume 1 billion orders per day and trading hours of 6.5 hours, which is 6.5 x 3,600 = 23,400 seconds. Average QPS is 1e9 / 23,400 ≈ 42,700, about 43,000 QPS. Peaks at the open and close can be 5x, giving about 215,000 QPS. Double-check: 43,000 x 23,400 ≈ 1.006e9, matching the daily total. These rates are high but not extreme; the hard part is doing them with microsecond-level latency and strict ordering.

High-level design: three flows

The trading flow is the critical path. A broker sends an order to the client gateway, which validates, authenticates and rate-limits it. The order manager runs risk checks and verifies funds in the wallet, then sends the order to the sequencer, which stamps it with a sequence ID. The matching engine matches it against the order book and emits executions, which pass back through the sequencer for outbound sequence IDs, then to the order manager and back to the client. Everything on this path must be as fast as possible.

The market data flow takes executions from the matching engine to the market data publisher, which builds order book snapshots and candlesticks and sends them to a data service that clients subscribe to. The reporting flow gathers orders and executions for reporting, settlement and compliance; it is not latency sensitive, so it can be off the critical path and favour accuracy and completeness.

Figure 1Trading critical path
Trading critical pathSINGLE TRADING SERVERorder/ ackcheckapprovedorderedinputexecutionsfillstradespublishreportsBrokerFIX / API ordersClient gatewayauth, validate, rate limitOrder managerorder state, fillsRisk checklimits + wallet fundsSequencer (out)stamps execution IDsMatching engineorder book per symbolSequencer (in)stamps order IDs 1, 2, 3Reportersettlement, complianceMarket data publisherbook snapshots, candlesData servicesubscribers
Every order crosses the sequencer on the way in and every execution on the way out, so the whole exchange is a deterministic function of one ordered stream. The boxed components share one server and talk over mmap, keeping network and disk off the hot path.

Deep dive: sequencer and matching engine

The sequencer is what makes the exchange deterministic. It stamps every inbound order with a monotonically increasing sequence ID and every outbound execution likewise. Ordered inputs plus a deterministic matching engine mean that replaying the same sequence always produces the same executions: functional determinism. The sequenced stream also acts as an event store, enabling replay, audit, and detection of missing messages via gaps in IDs.

The matching engine maintains one order book per symbol: a list of buy orders and a list of sell orders grouped by price level. Each price level holds orders in a doubly linked list in arrival order, and a hash map from order ID to node allows cancel in O(1). Adding an order appends to the tail of its price level; matching consumes from the head of the best opposite level; cancelling unlinks a node. With price levels themselves indexed, the core operations stay O(1) or close to it, which is essential for predictable latency. The default algorithm is FIFO (price-time priority): best price first, then earliest arrival. Some markets use pro-rata, allocating fills at a price level in proportion to order size.

Figure 2Price-time matching
Price-time matchingSellerBuyerSequencerMatching engineMarket data1. SELL 100 XYZ limit 10.002. seq 501: sell 100 @ 10.003. no bid ≥ 10.00: rest at tail of 10.00 asks4. BUY 150 XYZ limit 10.015. seq 502: buy 150 @ 10.016. fill 100 @ 10.00 against head of best ask7. rest remaining 50 on bids @ 10.018. execution 100 @ 10.009. exec 9001: sold 100 @ 10.0010. exec 9001: bought 100, 50 still open11. trade 100 @ 10.00, new best bid 10.01
The incoming buy crosses the spread, so it consumes the head of the best ask level at the resting order's price, $10.00, not its own limit. The unfilled remainder then rests at the tail of the $10.01 bid level.

Deep dive: performance on a single server

Latency equals the sum of time spent on each hop. Network round trips inside a data center cost tens to hundreds of microseconds and disk writes can cost milliseconds, so the most effective optimisation is to remove hops from the critical path. Modern exchanges put the gateway, order manager, sequencer and matching engine on one server, communicating via mmap-backed shared memory as a message bus rather than over the network. No disk sync or network call sits between receiving an order and matching it.

Each component runs an application loop that spins on a dedicated CPU core, with the thread pinned to that core so there are no context switches, no lock contention and warm caches. The loop polls for messages and processes them single-threaded, eliminating locks. State is managed with event sourcing: the sequenced input log on mmap is the truth, and in-memory state can be rebuilt by replaying it. The market data publisher uses ring buffers, pre-allocated circular arrays that avoid allocation and locking, the same idea behind the LMAX Disruptor.

  • One server for the critical path; no network or disk on the hot loop.
  • Single-threaded loops pinned to cores; no locks, no context switches.
  • mmap shared memory as the event bus; ring buffers for publishing.

High availability and fault tolerance

A single server is a single point of failure, so we run a hot-warm pair. The hot matching engine processes orders and emits executions; the warm instance receives the same sequenced events and processes them too, keeping identical state, but its output is discarded. If the hot instance dies, the warm one takes over almost instantly because determinism guarantees identical state. Across machines, the event log is replicated using Raft, which tolerates failures of a minority of nodes and elects a new leader automatically.

There is a trade-off. Consensus requires a majority acknowledgment over the network before an event is committed, which adds latency to the critical path. Exchanges must decide what failure they protect against and accept a small latency cost, or batch and pipeline replication to amortise it. Recovery time objectives in finance are strict, and a mistaken failover is costly, so failure detection must also be conservative.

Figure 3Hot-warm matching engines
Hot-warm matching enginesorderseventssame eventsheartbeatpromoteexecutionsOrder gatewaySequenced event logreplicated via RaftHot matching engineoutput is publishedFailover monitorpromotes warm on failureWarm matching enginesame input, same stateExecutions outOutput discardeduntil promoted
Both engines consume the same sequenced events and, being deterministic, hold identical order books; only the hot one's output is published. When heartbeats stop, the warm engine is promoted and resumes from the next sequence number.

Determinism, market data and fairness

Determinism has two meanings. Functional determinism ensures identical outputs from identical inputs. Latency determinism means nearly every order takes about the same time; we track it with p99 and p99.9 latencies, because spikes from garbage collection, page faults or noisy neighbours are what hurt traders. Techniques include pre-allocating memory, avoiding GC languages on the hot path or tuning them carefully, and disabling CPU frequency scaling.

For fairness, market data should reach all subscribers at the same time. TCP unicast sends to each subscriber in turn, so whoever is first in the list gets an edge. UDP multicast delivers one packet to many subscribers simultaneously, making distribution fair; reliability is added with sequence numbers and retransmission. Colocation lets firms rent servers inside the exchange's data center, buying lower network latency; this is a paid service and does not change the ordering rules once orders arrive.

Security, failure handling and wrap-up

An exchange is a high-value DDoS target. Isolate public services like web and market data dashboards from the private trading network so an attack on one cannot touch the other. Cache read-heavy public data, harden URLs against cache-busting query strings, and apply rate limiting and allowlists at the gateway. For failures, the sequenced event log is the backbone: any component can be rebuilt by replay, warm instances take over immediately, and Raft protects the log itself. The overarching lesson is that predictability, not raw average speed, is the defining requirement, and almost every design choice serves determinism.

Key numbers

Symbols
100
Orders per day
~1 billion
Trading window
6.5 h = 23,400 s
Average QPS
~43,000
Peak QPS (5x)
~215,000
Latency target
Low and stable at p99

Key terms

Limit order
An order to buy or sell at a specified price or better that may rest in the order book.
Market order
An order that executes immediately at the best available price.
Order book
The per-symbol collection of resting buy and sell orders organised by price level.
Sequencer
The component that stamps every inbound order and outbound execution with a monotonically increasing ID.
Price-time priority (FIFO)
A matching rule that fills the best price first and, at the same price, the earliest order first.
Functional determinism
The guarantee that the same ordered inputs always produce the same outputs.
Ring buffer
A fixed-size circular array used for lock-free, allocation-free message passing.
FIX protocol
A vendor-neutral messaging standard for exchanging securities transaction information.
UDP multicast
Delivering one packet to many receivers simultaneously, enabling fair market data distribution.

Common mistakes

  • Optimising average latency while ignoring p99 spikes that traders actually experience.
  • Spreading critical-path components across machines, adding network hops to every order.
  • Using unicast TCP fan-out for market data, which inherently favours some subscribers.
  • Allowing non-determinism such as wall-clock time inside the matching engine, breaking replay and hot-warm failover.
  • Skipping wallet fund locking, letting clients place orders backed by the same money twice.

Further study

  • LMAX Disruptor
  • The LMAX Architecture (Martin Fowler)
  • In Search of an Understandable Consensus Algorithm (Raft, 2014)
  • FIX Protocol specification
  • Aeron messaging

Now practise it