advanced 2 min answer

A trading platform must push live prices to hundreds of thousands of concurrent connections. What are the architectural constraints of that fan-out, and how does it differ from the order path?

zerodhawebsocketsfanoutconflationconnections
Show the full answer Hide the answer

The constraints

  • Connection state is the scaling unit, not request rate. Each connection consumes memory, a file descriptor and a share of the event loop, so capacity is measured in connections and the cost is paid whether or not anyone is trading.
  • Fan-out amplification. One price update multiplied across every subscriber is the real workload. A hundred thousand subscribers to one instrument means one input event becomes a hundred thousand output events, and the CPU cost is in serialisation and syscalls rather than in any business logic.
  • Reconnection storms. When a fan-out node fails, all its connections reconnect simultaneously — usually to the remaining nodes, which are now also under-provisioned. Jittered reconnect with capacity headroom is a requirement, not a refinement.

The techniques that make it tractable

  • Conflation. A subscriber that cannot keep up receives the latest price, not a backlog of stale ones. This is the correct overload behaviour for market data and is categorically unavailable to order flow, which is precisely why the two cannot share a transport.
  • Subscription-based filtering at the edge, so a client receives only its watchlist rather than the full feed.
  • Batching by time window. Sending accumulated updates every 100ms rather than each update individually reduces syscalls by an order of magnitude at a latency cost that is invisible on a chart.
  • Binary encoding, since serialisation dominates at this fan-out and text formats are several times more expensive.
  • Separate the fan-out tier from everything else, with its own capacity and its own failure domain.

Why the order path is a different system

Orders are low volume, must never be lost, require acknowledgement, and are stateful per user. Prices are high volume, individually disposable, and identical across users. The correct overload behaviour for one is the worst possible behaviour for the other, so sharing a connection pool, a process or a queue between them means the price burst starves the orders.

The classic incident is not a trading system failing under trading load — it is a trading system failing because everyone opened the app at once and the read traffic exhausted a resource the order path needed.