Systems & building

Messaging protocols

structural
Reviewed 4 June 2026. As of 2026: a permanent feature of the market, not an edge that decays.

FIX for order entry, binary protocols for speed, multicast for market data. The wire format is where latency is won or lost before your strategy even runs.

See it move

A FIX order messagedecode itIX-FIX
8=FIX.4.2|9=112|35=D|49=BUYSIDE|56=SELL|34=4|52=20260604-13:20:01|11=ORD-7|21=1|55=BTC|54=1|38=1.5|40=2|44=68250.5|59=0|10=131|

What to notice. FIX is just tag=value pairs separated by a delimiter. Human-readable and ubiquitous for order entry, but verbose, which is why latency-sensitive venues offer compact binary protocols for the hot path and keep FIX for the slow one.

Why are there two different protocols, one for data, one for orders?

Because the two flows have opposite requirements. Market data is one venue broadcasting to thousands of listeners, so it uses multicast UDP (send once, everyone receives) and tolerates the occasional lost packet via a recovery channel. Order entry is a private, reliable conversation between you and the matching engine, so it uses TCP (or a reliable session protocol): you cannot afford to silently lose an order.

The intuition is two kinds of speaking. A stadium announcer (market data) shouts once and the whole crowd hears it: that is multicast, and it is efficient precisely because the sender does not track who is listening. A phone call to place a bet (order entry) is point-to-point and must be reliable: you need to know the order arrived and what happened to it.

So market data is multicast, fan-out, fire-and-forget. The exchange publishes every book change once onto a multicast group; every subscriber's network card receives the same packets simultaneously, a deliberate fairness property, since no participant is told first. UDP has no retransmission, so the protocol carries sequence numbers and a separate recovery path for when you miss one. Order entry, by contrast, is point-to-point over a reliable session. Your gateway holds a logged-on connection to the matching engine; every order, cancel and execution report flows over it with guaranteed, ordered delivery, and FIX layers its own application-level sequencing on top so a dropped session can resume without losing or duplicating an order.

This split is the structural fact of exchange connectivity, and it shapes the whole low-latency stack: the inbound multicast firehose is where kernel bypass earns its keep, while the outbound order path is where determinism and pre-trade risk checks live. You can decode and reconstruct an order from the message viewer above and see exactly how each channel carries it.

What is FIX, and what does a FIX order message look like?

FIX (the Financial Information eXchange protocol, in use since 1992) is a tag=value text protocol that became the cross-venue standard for order entry and post-trade. A message is a list of numbered fields joined by a delimiter: 35=D35{=}D means "this is a new order", 54=154{=}1 means "buy". It is verbose and human-readable: easy to integrate against, but heavy on the wire compared with binary.

A NewOrderSingle (35=D35{=}D) carries, among others: tag 11 the client order id, 55 the symbol, 54 the side (1 buy, 2 sell), 38 the quantity, 40 the order type (1 market, 2 limit), 44 the price and 59 the time-in-force. The matching engine answers with an ExecutionReport (35=835{=}8) reporting the order as new, filled, cancelled or rejected. The decoder above hover-explains each tag so the wire format stops being opaque.

Why FIX persists in 2026: it is universal. A single FIX engine speaks to dozens of venues and brokers using per-venue dialects rather than entirely separate code. For a system that is not racing for the last microsecond (most stat-arb, slower market making, cross-venue work) FIX is perfectly adequate and dramatically cheaper to build against, which is why it is the natural default for the solo builder. Why FIX loses the speed race: the text is large and must be parsed field-by-field (variable layout, delimiter scanning) and that encode/decode costs microseconds you cannot get back. That is the gap the binary protocols close, and FIX itself answered with binary encodings (SBE and FAST) of its own.

What are the native binary protocols: ITCH, OUCH and SBE?

Native binary protocols pack a message into a fixed byte layout with no text, so it parses at fixed offsets in nanoseconds. ITCH is Nasdaq's market-data feed; OUCH is Nasdaq's matching binary order-entry protocol; SBE (Simple Binary Encoding) is the FIX-community standard that CME and others use for both. Binary is the speed tier's wire format.

ITCH (Nasdaq TotalView-ITCH) is an order-by-order, or market-by-order, feed. It streams Add Order, Order Executed, Order Cancel and Order Delete messages keyed by an order reference number, so a subscriber can reconstruct the full book and every order's queue position: the granularity the limit order book and price-time priority depend on, and the same granularity recorded data preserves. OUCH is Nasdaq's binary order-entry protocol (Enter Order, Cancel Order, Order Accepted, Executed) far leaner than FIX and designed for the latency-sensitive order path. SBE is schema-driven: a schema describes each field's type and offset, so the decoder is generated and the message is read by pointer arithmetic, not parsing; CME's MDP 3.0 market data and iLink order entry are SBE-encoded.

The pattern is universal even where the names differ. The speed-sensitive path is fixed-layout binary; FIX survives where breadth and integration speed matter more than microseconds. Always read the venue's own published spec for the exact message set: the field tables are authoritative and they evolve (the Nasdaq TotalView-ITCH and OUCH specs, and the CME MDP 3.0 / iLink SBE specs). The binary view in the decoder above shows the same order as a byte-laid-out frame with offsets and a "bytes on the wire" counter, so the size win over FIX is concrete.

How does a multicast feed stay correct: sequencing and gap recovery?

Every multicast packet carries a sequence number. The feed handler tracks the next expected number; if one is skipped, it has detected a gap (a lost packet) and must recover before trusting its book. Venues provide recovery in layers: a redundant A/B line, a snapshot/refresh channel, and a TCP retransmission service. Until the gap is filled, the book is stale and must not be traded on.

Sequence numbers turn "did I miss anything?" into an exact arithmetic check. Because the feed is incremental (each packet is a delta to the book, not the whole book) a single missing packet corrupts the book from that point on, so you cannot just carry on as if nothing happened.

A gap is detected the instant the received sequence number jumps past the expected one. Any non-zero gap means the in-memory book has diverged from the venue's and is no longer tradeable until recovery completes.
gap=sreceivedsexpected,book valid    gap=0\text{gap} = s_{\text{received}} - s_{\text{expected}}, \qquad \text{book valid} \iff \text{gap} = 0

The defences stack from cheap-and-fast to slow-and-certain. The A/B line (line arbitration) is the first: the venue publishes the same feed on two independent multicast groups, the handler listens to both and takes whichever packet arrives first for each sequence number, so a loss on one line is covered by the other. The snapshot / refresh channel is a periodic full-book image that lets a handler which has fallen badly behind re-synchronise from a known-good state and then resume applying increments. Retransmission is a reliable TCP side-channel to request the specific missing numbers: slower, used only when A/B and snapshots are not enough. The honest engineering point: detecting and recovering from gaps correctly is most of what a feed handler is, and getting it subtly wrong (trading on a silently-stale book) is a classic, expensive bug. The same message stream is what a faithful backtest must replay deterministically and what fills the terabytes-per-day data volume.

What does a feed handler do, and why normalise across venues?

A feed handler is the software that decodes a venue's wire protocol into your system's internal events and reconstructs the book from the increments. Normalisation maps every venue's idiosyncratic message set onto one common internal representation, so the strategy code is written once against a uniform event model rather than against ITCH, then SBE, then a crypto JSON feed.

The feed handler's job runs in a strict order: receive packets, check the sequence and recover any gap, decode each message at its byte offsets, apply it to the in-memory book, and emit a normalised internal event (an AddOrder, a Trade, a BookUpdate) that the rest of the system consumes. It is the first stage of the system pipeline and the component most sensitive to both latency and correctness.

Normalisation is what makes a multi-venue system tractable. CME SBE, Nasdaq ITCH, a fragmented set of equity venues and a crypto exchange's WebSocket diff feed all describe the same underlying object, a limit order book, in mutually incomprehensible formats. The handler erases those differences so the strategy sees one clean stream. And the cross-market reality is encouraging for a newcomer: in crypto and on prediction markets the "protocol" is usually JSON or protobuf over a WebSocket with a snapshot-plus-diff model: conceptually identical (sequence numbers, gap recovery, incremental updates) but far easier to integrate, which is part of why those venues are where the independent builder starts.

What AI changes: generating a conformant parser and normaliser from a published spec is now largely an LLM-assisted task: work that used to gate a one-person shop is an afternoon's scaffolding. The judgement does not move: handling the recovery edge cases, getting the timestamps right, and validating against a recorded tape stay human (see what AI changes for HFT). The wire format is not where the edge is; getting onto it cleanly is table stakes.

Worked example

Take a single limit order, buy 100 lots of a symbol at 50.01, limit, day, and encode it both ways, as of 2026 (illustrative and schematic; read the venue spec for exact byte layouts). You can reproduce both in the decoder above.

As FIX, with | standing for the SOH delimiter, the message reads roughly 8=FIX.4.4 | 35=D | 11=ORD-001 | 55=XYZ | 54=1 | 38=100 | 40=2 | 44=50.01 | 59=0: FIX 4.4, a NewOrderSingle, client order id ORD-001, symbol XYZ, side buy, quantity 100, type limit, price 50.01, day. That is roughly 60–120 bytes of text, parsed by scanning for delimiters and looking up each tag. As native binary (SBE/OUCH-style), the same order is a packed frame, schematically [msgType:1][clOrdId:8][symbolId:4][side:1][qty:4][price:8][tif:1], in roughly a third of the bytes, at fixed offsets: side is always byte N, price always bytes M to M+7. No scanning; the decoder reads it by pointer arithmetic.

The same order, two encodings: binary trims the byte count to about a third and replaces delimiter-scanning with constant-time offset reads, saving single-digit microseconds per message.
bbinary13bFIX,ΔtdecodeO(µs) per messageb_{\text{binary}} \approx \tfrac{1}{3}\,b_{\text{FIX}}, \qquad \Delta t_{\text{decode}} \sim \mathcal{O}(\text{µs}) \text{ per message}

The figure to internalise: the binary encode/decode saves single-digit microseconds per message versus FIX, and the byte reduction matters most for the inbound multicast firehose, where at peak you are decoding millions of messages per second. For a non-speed strategy those microseconds are irrelevant and FIX's breadth wins; for the speed tier they are the whole point. The protocols themselves are slow-moving infrastructure: the choice between them is an economics decision about your strategy's latency budget, not a question of which is "better".

Where this fits