What is a stock trading system?
A brokerage platform like Robinhood lets retail investors trade equities through a mobile app or website. Under the hood, the broker verifies the user's available funds, sends orders to an external stock exchange via its API, tracks the order lifecycle as fills arrive, and keeps the account balance accurate at all times.
The broker acts as a middleman between the user and an external stock exchange. Users want instant confirmation of order acceptance and an always-correct view of their buying power, yet the exchange responds asynchronously, may partially fill an order over multiple events, and can time out unpredictably. The core difficulty is preserving a correct account balance while bridging that gap.
You: "Do we need to support market orders, stop-loss, or other order types, or is the scope limited to limit orders?"
Interviewer: "Limit orders only. Market orders, stop-loss, options, and margin trading are all out of scope."
Takeaway: Limiting the scope to limit orders removes a lot of ambiguity around reservation and validation. That lets the design focus on order lifecycle rather than order-type complexity.
You: "If two buy orders for the same account arrive at the same time, must the system guarantee neither can overdraw the account, or is a brief overdraft followed by a correction acceptable?"
Interviewer: "No overdraft under any circumstance. Correctness is the top priority."
Takeaway: The account cannot be allowed to temporarily overdraw just because two orders arrive together. That guarantee has to hold under concurrency.
You: "If we submit an order to the exchange and no fill callback arrives within a reasonable time, should we treat the order as failed, leave it pending indefinitely, or eventually determine the definitive outcome another way?"
Interviewer: "The order should be treated as uncertain after a bounded wait. Leaving a submitted order stuck indefinitely is not acceptable, and the system must eventually determine the definitive outcome directly from the exchange."
Takeaway: The system needs an explicit uncertain state and a way to resolve it later when exchange callbacks do not arrive on time.
You: "When the exchange sends a fill notification, do clients need guaranteed ordered delivery, or is best-effort push with the ability to recover authoritative order state from a dedicated endpoint sufficient?"
Interviewer: "Best-effort push is fine for the live channel. Clients must always be able to recover authoritative order state from a GET endpoint."
Takeaway: Fast client updates and authoritative recovery serve different needs here. The live channel can optimize for speed, but the system still needs one canonical recovery path.
You: "Should the buying-power hold stay at the full original reservation until the order completes, or should it be reduced incrementally as partial fills arrive?"
Interviewer: "The hold should be reduced as fills arrive. Holding the full original amount unnecessarily restricts available buying power while the order is still in progress."
Takeaway: Partial fills have to change the user's available buying power as they happen, which means reservation release cannot wait until the order reaches a terminal state.
You: "If a cancel request and an exchange fill arrive at the same time, who is the authority: does the cancel win, the fill win, or whichever was recorded first?"
Interviewer: "The exchange is the authority. If the exchange reports a fill, that fill stands regardless of whether a cancel was also requested. The cancel request is acknowledged as best-effort."
Takeaway: Cancel is best-effort from the broker side, so the design has to handle the race where a fill still arrives after the user asked to cancel.
99.95% availability.p95 < 500 ms. Real-time fill updates to the client target p95 < 2 s.1M active users and 5M orders per trading day, with peak queries per second (QPS) concentrated during market open and close windows.We base the calculations on a single trading day. The aim is not exact numbers; it's to highlight which figures drive contention, timeout budgets, and infrastructure sizing.
| Metric | Assumed value | Used for |
|---|---|---|
| Active users | ~1M | Account store size, session infrastructure |
| Orders per trading day | ~5M | Order service write throughput, database sizing |
| Peak order rate (market open) | ~2,000/s | API gateway capacity, buying-power contention budget |
| Average fills per order | 1–3 | Fill processing pipeline throughput |
| Fill callback latency from exchange | 50–500 ms | Timeout tuning, reconciliation poller frequency |
| Concurrent WebSocket connections (peak) | ~200k | Real-time notification infrastructure |
The numbers that truly shape the architecture are the peak order rate, which drives contention on the buying-power reservation path, and the fill callback latency, which determines how long orders remain in an uncertain state. The daily volume is moderate, but the burst at market open is where correctness under concurrency becomes non-negotiable.
Out of scope (below the line)