WebSocket order-book sync: detect gaps and recover safely
The most dangerous order-book bug is quiet: the socket is connected, prices look plausible, and one missed delta has made the local depth wrong. A reliable bot treats the book as a validated state machine—seeded by a snapshot, advanced only by continuous updates, and invalidated immediately when continuity is uncertain.
A local order book is a derived cache
An order book contains bids and asks keyed by price. A full snapshot supplies many current levels; incremental messages then add, replace, or remove levels. The venue remains the source, and your local copy is only valid while it follows that venue's sequence contract.
Before implementing depth, understand what an order book represents. Then read the current official API specification for the exact channel. Important differences include:
- whether an update carries an absolute quantity or a signed change;
- whether zero quantity deletes a level;
- whether update IDs are single values, ranges, or per-channel sequences;
- how the first delta must overlap the snapshot identifier;
- whether sequence resets are expected after reconnect or maintenance;
- how a checksum is constructed, ordered, formatted, and validated.
A correct algorithm for one venue can silently corrupt another venue's book. Keep each synchronization procedure inside a venue-specific adapter with recorded conformance fixtures.
Buffer first, then join snapshot and stream
A common high-level bootstrap looks like this, but the official venue-specific procedure takes priority:
- mark the symbol book
SYNCINGand block book-dependent decisions; - connect and subscribe to the incremental stream;
- buffer deltas without applying them to an unseeded book;
- fetch a full snapshot and capture its update identifier;
- discard buffered events that the snapshot already includes;
- find the first event that validly connects to the snapshot under the documented rule;
- apply subsequent events in order while verifying continuity;
- run crossed-book, freshness, depth, and optional checksum checks;
- mark the book
LIVEonly after every gate passes.
book state machineEMPTY -> SYNCING -> LIVE
^ | |
| v v
+----- INVALID <-- GAP / CHECKSUM / STALE
Only LIVE may feed book-dependent signals.
Buffer bounds matter. If snapshot retrieval is slow and the queue exceeds a memory or age limit, discard the attempt and restart with backoff. Applying an arbitrarily old buffer defeats the freshness goal.
Validate continuity and book invariants
After bootstrap, every applied event must connect to the prior accepted state according to the venue's documented sequence rule. A duplicate may be safely ignored if the protocol defines it; a forward gap invalidates the cache; an unexplained backward jump may indicate replay or a new stream epoch. Do not “skip ahead” because the top prices still look believable.
| Check | What it detects | Response |
|---|---|---|
| Sequence continuity | Missing, replayed, or reset updates | Invalidate and resync |
| Checksum | Content differs despite sequence flow | Invalidate and resync |
| Best bid < best ask | Crossed or corrupt local book | Stop use; investigate/resync |
| Event age | Connected but stalled feed | Mark stale; reconnect/resync |
| Nonnegative sizes | Wrong delta semantics or parse bug | Reject update; invalidate |
| Reference comparison | Drift from periodic snapshot/ticker | Alert and rebuild |
Use exact decimal price keys or venue-native integer ticks. Binary float keys can split one logical price into multiple map entries. Keep bids ordered descending and asks ascending, while pruning only to a depth that still supports the strategy and checksum rules.
Track event time and receive time separately. Clock alignment guidance is in trading-bot clock synchronization; elapsed freshness should use a monotonic timer.
A gap is a risk event, not just a reconnect counter
When continuity fails:
- atomically set the book to
INVALID; - stop publishing book-derived prices, imbalance, liquidity, and slippage estimates;
- block new orders whose decision or sizing depends on those values;
- clear the suspect book and buffered chain;
- reconnect or resubscribe with bounded exponential backoff and jitter;
- repeat the full snapshot-and-delta bootstrap;
- require a minimum healthy interval or event count before resuming;
- reconcile private order state separately if the account stream also had a gap.
A retry storm can worsen an exchange incident and breach API rate limits. Put resync requests through a priority-aware limiter, cap concurrent symbol recoveries, and add jitter so all workers do not reconnect together.
Risk-reducing actions may be allowed through a separate approved reference-price path, but this must be designed in advance. Never route a stale depth estimate into a marketable limit merely because the exit is urgent.
Corrupt recorded streams on purpose
Capture representative snapshots and streams where the venue permits, redact private data, and create deterministic fixtures. Test:
- updates arriving while the snapshot is in flight;
- the exact first valid overlap at the snapshot boundary;
- duplicate, missing, delayed, and out-of-order events;
- sequence reset after reconnect;
- wrong checksum, zero-size deletion, and malformed decimals;
- buffer overflow and a snapshot slower than the freshness limit;
- a socket that remains open but stops delivering;
- many symbols resynchronizing during a venue incident.
Assert not only that the book eventually recovers, but that no book-dependent signal escapes while state is syncing, stale, or invalid. Monitor book state, event age, sequence gaps, checksum failures, resync duration, buffer depth, reconnect count, and time since the last trusted snapshot. The transport split in WebSocket vs REST for trading bots shows where this cache fits in the wider system.
Frequently asked questions
Why does a trading bot need an order-book snapshot and WebSocket updates?
The snapshot provides a complete starting state, while WebSocket deltas efficiently describe subsequent changes. A local book is valid only when the bot follows the venue's documented procedure for joining them and verifies update continuity.
What is a WebSocket sequence gap?
It is evidence that one or more expected updates were missed, arrived outside the accepted sequence, or belong to a different stream epoch. The local order book may then be wrong even though the connection remains open, so the bot should mark it invalid and rebuild from a fresh snapshot.
Can a bot keep trading during order-book resynchronization?
It should block signals, sizing, and order policies that depend on the invalid book. Independent risk-reducing actions may follow a separate approved data path, but the bot must not treat stale depth as current. Resume only after the snapshot, sequence, freshness, and sanity checks pass.
Does every exchange use the same order-book synchronization algorithm?
No. Venues differ in update identifiers, sequence ranges, snapshot timing, checksum rules, reset behavior, and whether a message contains absolute quantities or changes. Implement each adapter from the current official specification and test it with recorded and deliberately corrupted streams.