At a glance#
| Number | Value | What it drives |
|---|---|---|
| Order messages, record day | 21.89 billion (24 March 2026) | ~973,000 / s average over 22,500 s |
| Trades, record day | 201 million | ~109 messages per trade: size by messages |
| Published capacity | ~5 million messages / s | expiry bursts near it (est. ~4.3M / s) |
| Matching partitions (design) | ~20, one thread each | ~500k / s each (assumed), half-loaded at peak |
| Full tick-by-tick feed | ~2 Gbit/s at peak (est.) | multicast once, not TCP per subscriber |
| Journal | ~2.2 TB / day · ~3.5 Gbit/s to near site (est.) | synchronous near site, async DR |
| Recovery | declare in 30 min · restore in 45 min after (SEBI) | live DR drills, failover as one unit |
| Investors | 129.09 million unique (31 March 2026) | 1,325 members, 200,000+ terminals |
Architecture#
DiagramOrder entry, one sequenced core, and everything that reads its output
%% title: Order entry, one sequenced core, and everything that reads its output
flowchart TD
MEM@{ icon: "sd:users", label: "Members<br/>brokers' offices · co-location racks" }
GR@{ icon: "sd:router", label: "Gateway router<br/>least-loaded gateway" }
GW@{ icon: "sd:gateway", label: "Gateways<br/>connection rate · sliding window" }
CHK["Checks before the book<br/>price band · freeze qty · value · status"]:::service
SEQ["Sequencer per partition<br/>next number · journal"]:::hot
JRN@{ icon: "sd:log", label: "Journal<br/>input log" }
NS@{ icon: "sd:database", label: "Near site<br/>synchronous copy" }
DR@{ icon: "sd:region", label: "DR site, Chennai<br/>asynchronous mirror" }
ME["Matching thread<br/>in-memory books · price-time"]:::core
MD@{ icon: "sd:network", label: "Market data<br/>multicast A and B feeds" }
CLR["NSE Clearing<br/>novation · real-time margins"]:::core
SURV@{ icon: "sd:monitor", label: "Surveillance<br/>replays the log" }
MEM ==> GR
GR -.->|"assigns"| GW
GW ==> CHK ==> SEQ
SEQ ==> JRN
SEQ ==> ME
JRN ==> NS
JRN -.-> DR
ME ==> MD
ME ==>|"trades"| CLR
ME --> SURV
CLR -.->|"disable member"| CHK
class MEM client
class GR,GW edge
class JRN,NS store
class DR external
class MD queue
class SURV service- One line decides "first": gateways are parallel and stateless; the sequencer orders; every output reads one ordered stream.
- Margin is a status bit: NSE Clearing computes it from trades and disables a member on a breach; gateways only read the bit.
- Fair by transport: one multicast packet per tick, copied by the switches, never sent in login order.
DiagramZoom-in · one partition with output gating
%% title: Zoom-in · one partition with output gating
flowchart TD
G1@{ icon: "sd:gateway", label: "Gateways<br/>admitted messages" }
SEQ["Sequencer<br/>assign seq · journal"]:::hot
ME["Matching thread<br/>applies in sequence"]:::core
HS["Hot standby<br/>same log · same code"]:::core
NS@{ icon: "sd:database", label: "Near site<br/>synchronous journal" }
GATE{"Input durable on<br/>standby and near site?"}
OUT@{ icon: "sd:stream", label: "Acks · trades · ticks<br/>released in order" }
G1 ==> SEQ
SEQ ==> ME
SEQ ==> HS
SEQ ==> NS
ME ==> GATE
HS -.->|"book hash every N"| GATE
NS -.->|"ack"| GATE
GATE ==>|"yes"| OUT
class G1 edge
class NS store
class OUT queueKey flows#
DiagramOne order from a broker's session to a trade, a tick and clearing
%% title: One order from a broker's session to a trade, a tick and clearing sequenceDiagram autonumber participant B as Broker participant G as Gateway participant S as Sequencer participant M as Matching thread participant D as Multicast stream participant C as NSE Clearing B->>G: new order · 1 lot @ 4.20 G->>G: rate · price band · value · member status G->>S: forward S->>S: next seq · journal to standby and near site S->>M: apply in sequence M-->>G: ack · order number = partition + sequence M->>M: crosses resting sell at 4.20 M-->>G: confirmations to both members M->>D: tick · one packet for every subscriber M->>C: trade · applied once by sequence Note over S,M: outputs leave only after the input is durable
DiagramA session drops · replay, then act on what happened
%% title: A session drops · replay, then act on what happened
sequenceDiagram
autonumber
participant B as Broker
participant R as Gateway router
participant G as New gateway
participant L as Output log
B->>R: logon after drop
R-->>B: new gateway · session key
B->>G: download stream 7 from last seq
G->>L: this trader's messages after that seq
L-->>B: ACK new order · TRADE on older order
B->>G: modify older order · last activity reference
alt reference matches
G-->>B: modified
else order changed since
G-->>B: rejected · stale version, re-read
end
Note over B,G: ask, don't resendDiagramCritical systems fail · halt, declare, fail over as one unit
%% title: Critical systems fail · halt, declare, fail over as one unit sequenceDiagram autonumber participant O as Operations participant P as Primary site participant D as DR site participant M as Members P-->>O: risk, index, surveillance down · trading healthy O->>P: halt all segments O->>M: trading halted Note over O: declare within 30 min · restore within 45 min O->>D: activate trading, risk, clearing, index, surveillance D->>D: replay journals to last replicated seq M->>D: logon via router · download messages Note over D,M: multicast streams restart at seq 1 D->>M: pre-open call auction, then continuous trading
Data model#
DiagramCore entities
%% title: Core entities
classDiagram
class Partition {
+partitionId : int
+epoch : int · fences a deposed sequencer
+lastSeq : long
+contracts : list
}
class Book {
+contract : token
+bids : price levels · FIFO queues
+asks : price levels · FIFO queues
}
class Order {
+orderNo : partition and sequence
+side : BUY or SELL
+price : int · in ticks
+qty : int
+lastActivityRef : long · version for modify
+clientCode : string
+algoId : int · if algorithmic
}
class Session {
+connectionId : int
+subscribedRate : msgs per second
+lastSeqSeen : long per stream
}
class Trade {
+partition : int
+seq : long · unique with partition
+buyOrder : orderNo
+sellOrder : orderNo
+qty : int
+price : int · in ticks
}
Partition "1" --> "many" Book : owns
Book "1" --> "many" Order : queues
Session "1" --> "many" Order : sends
Order "1" --> "many" Trade : fills in- One instrument lives in exactly one partition; hot weekly strikes are spread across partitions between sessions.
- Downstream readers keep a high-water mark of (partition, seq), so a redelivered trade is applied once.
Lifecycle#
DiagramAn order, from entry to done
%% title: An order, from entry to done stateDiagram-v2 [*] --> CHECKED: gateway admits it CHECKED --> REJECTED: rate, band or limit fails CHECKED --> SEQUENCED: sequencer numbers it SEQUENCED --> OPEN: rests in the book SEQUENCED --> FILLED: crosses fully OPEN --> OPEN: modify with current reference OPEN --> PART_FILLED: trades in part PART_FILLED --> FILLED: rest trades OPEN --> CANCELLED: cancel or close PART_FILLED --> CANCELLED: cancel or close FILLED --> [*] CANCELLED --> [*] REJECTED --> [*] class FILLED ok class REJECTED bad class PART_FILLED queue
Decisions#
| Decision | Chose | Over | Because |
|---|---|---|---|
| Who decides first | Sequence number | Gateway clocks | clocks drift and tie |
| Concurrency | One thread per partition | Locks on a book | lock order can't be replayed |
| Time | Sequenced events | Reading the clock | replay must match |
| Durability | Output gating, sync near site | Async replication | nothing acked is lost |
| Margin | Status bit from clearing | Inline check per order | gateway checks stay local |
| Market data | Multicast, A/B, recovery | TCP per subscriber | equal by construction |
| Pre-open close | Random in 8th minute | Fixed instant | no prize for being last |
When it breaks#
| Failure | What users see | Contain it with |
|---|---|---|
| Runaway member algo | its own rejects, then disconnect | connection rate · cut at 2× · kill switch |
| Primary engine dies | brief pause, same book | gated outputs · hash-checked standby · epoch |
| Session drops mid-burst | unknown order state | message download by sequence |
| Multicast packet loss | nothing, usually | feed B · rate-limited TCP recovery |
| Risk or index system down | market halted | halt · declare in 30 min · DR as one unit |
| Near-site link degrades | slower acks | shed traffic · stay synchronous · halt if lost |
Say it in the interview#
- The order is the product: one sequencer per partition decides "first"; no clock does.
- Determinism makes replication cheap: replicate inputs, replay the log, compare book hashes.
- Nothing acked that can't be replayed: outputs wait until the input is on the standby and the near site.
- Push back at the member's door: per-connection rates in a sliding window; the core never queues a burst.
- Ask, don't resend: a dropped session replays its stream by sequence; modifies carry the last-activity reference.
- Fairness is a transport property: SEBI's 2019 order described how a TCP feed in login order, and a lightly loaded backup, could give some members ticks first; multicast sends one packet to everyone.
- The market is bigger than the engine: in February 2021 the trading system was fine and NSE still halted, because the risk system wasn't.