System design sample solution

System design: stream live stock prices

A step-by-step system design answer you could actually give in 60 minutes.

System design interview · Sample 60-minute answer · Not Bloomberg's actual design · Independent, not affiliated with Bloomberg

The system design question

Design a system that takes live prices from stock exchanges and streams them to thousands of users. Each user only wants the tickers on their watchlist, and updates should arrive within milliseconds.

Agree on the scope (5 minutes)

Say up front what you're covering.

We'll designWe'll skip
Taking in exchange feedsPlacing trades
Putting prices in one formatHistorical charts
Sending each user their tickersPrice alerts
Showing a price straight away on subscribeNews

Then agree on what "good" means:

  • Fast: a price change should reach screens within a few milliseconds inside our network.
  • In order: a user should never see an older price after a newer one.
  • Complete: no missed updates, or at least we notice and fix them.
  • Fair: one slow user's connection can't slow down everyone else.

Rough numbers (5 minutes)

Made up, but reasonable: 100,000 tickers, about 1 million price updates a second at market open, and 300,000 users online with about 50 tickers each.

1M
price updates per second at the open
300K
users connected
15M
user-to-ticker subscriptions
100K+
watchers on the most popular tickers
QuestionRough mathWhat it means
How many messages go out?Each update × everyone watching that tickerFar more than come in, so sending is the expensive part
How much is one popular update?1 update × 100,000 watchersOne price change can turn into 100,000 messages
How fast can a screen use updates?People can't read 50 changes a secondWe can send only the latest price a few times a second

The overall design (10 minutes)

Exchange feedsraw pricesFeed handlersone format, in orderPrice streamsplit by tickerFan-out serverstrack subscribersUser screensopen connection
Prices are cleaned up once, then copied out to only the servers and users who want them.
  1. Feed handlers connect to each exchange and convert prices into one format.
  2. They publish each price to a stream, split up by ticker so each ticker's prices stay in order.
  3. Users' screens keep an open connection to a fan-out server and tell it which tickers they want.
  4. Each fan-out server only listens for the tickers its own users want.
  5. When a price arrives, the server sends it to each of its users watching that ticker.

What the apps need to do

ActionWho does itWhat's sent
SubscribeUser's screenA list of tickers to start watching
UnsubscribeUser's screenTickers to stop watching
Price updateOur serversTicker, price, time and a sequence number
SnapshotUser's screenTickers, and we return their latest prices

What we store and where

DataWhere it goesWhy
Latest price per tickerIn memory on every fan-out serverNew subscribers get a price straight away
Who's watching whatIn memory on each fan-out serverOnly that server needs it
The price streamA message log, split by tickerKeeps order and lets servers catch up
WatchlistsDatabaseSaved so users get them back after logging in

Step 1: Taking prices in, in order (10 minutes)

Every exchange formats its data differently, so feed handlers convert everything once, close to where it comes in. Exchanges number their messages, and if a number's missing, the handler asks the exchange to resend it.

Run two feed handlers per exchange. If one dies the other keeps going, and the sequence numbers let us drop the duplicates.

The handlers publish into a stream split up by ticker, like a message queue. Because a ticker's prices always land in the same partition, they stay in order.

Step 2: Sending prices out (15 minutes)

Each fan-out server keeps a simple map from ticker to the users watching it. It only listens to the partitions for tickers its users care about, so no server handles everything.

Every server also keeps the latest price for each ticker in memory. When someone subscribes, they get it immediately, without waiting for the next change. That's basically a cache.

Screens keep a connection open, so prices are pushed the moment they arrive. Polling would add delay and a lot of wasted requests.

Slow connections

Some users are on slow networks. If we queue every update for them, their queue grows forever. So for each slow user, keep only the latest price per ticker and send that when they're ready. They see fewer updates, but never old ones.

Step 3: Very popular tickers (5 minutes)

A big name might have 100,000 watchers. Spread those users across many fan-out servers, so each server sends to a few thousand of them instead of one server sending to everyone.

Assign tickers to stream partitions with sharding, and give the busiest tickers more room so they don't crowd out quieter ones.

Choices you should be able to defend

We choseInstead ofBecauseWe'd reconsider if
Pushing over an open connectionScreens polling for pricesIt's much faster and wastes far lessClients were on networks that block long connections
Sending only the latest price to slow usersSending every single tickTheir queue can't grow forever, and they see current pricesUsers needed every tick, like for trading tools
A shared message logFeed handlers sending straight to serversServers can join, leave and catch up easilyWe needed the lowest possible latency, and the extra hop cost too much
Splitting by tickerSplitting by exchangeKeeps each ticker in orderOne exchange's feed needed special handling

What could go wrong (5 minutes)

What happensWhat we do about it
A feed handler crashesIts twin keeps going, and sequence numbers drop duplicates
A message from the exchange is missingAsk the exchange to resend, and hold that ticker until it arrives
A fan-out server diesScreens reconnect to another server and get a snapshot of the latest prices
A user's connection is slowSend only their latest prices so they don't fall further behind
An exchange feed stopsMark its prices as stale on screen, so nobody trusts an old number

Follow-up questions (5 minutes)

How would you add price alerts?

A separate job reads the price stream and checks each update against users' alert levels for that ticker. Store which alerts already fired so they don't fire twice.

Not everyone can see every exchange. How do you handle that?

Check what each user is allowed to see when they subscribe, and refuse tickers they're not paying for. That's access control.

How would you show historical charts?

Have another consumer write prices into storage built for time ranges, completely separate from the live path.

How the 60 minutes add up

MinutesWhat you're doing
0–5Agree on what you're building
5–10Rough numbers
10–20Draw the overall design
20–30Taking prices in, in order
30–45Sending prices out
45–50Very popular tickers
50–55What could go wrong
55–60Follow-up questions

Key concepts used here

Further reading

We wrote this sample answer ourselves.

Practice Loop is independent and isn't affiliated with or endorsed by Bloomberg.