Problem Statement
Design a system that lets users set alerts on stock prices (e.g., "notify me when AAPL crosses $200") and delivers notifications in near real-time when conditions are met.
The system must handle high-volume price updates and millions of user-defined alerts.
Requirements
Functional:
- Users create alerts: (stock symbol, condition, threshold)
- System ingests real-time price updates for thousands of stocks
- When a price crosses a user's threshold, send a notification
- Support multiple conditions (above, below, % change)
Non-Functional:
- Near real-time alerting (sub-second)
- Handle high-frequency price updates (thousands/sec per stock)
- Millions of active alerts
- Reliable delivery (no missed alerts)
- Scalable
What the Interviewer Expects
- Push vs Pull mechanism — the core discussion:
- Pull: clients poll for price → doesn't scale, high latency
- Push: price updates flow to a matching engine that pushes notifications → preferred
- Alert storage & indexing — index alerts by stock symbol. When a price update arrives for AAPL, quickly find all alerts watching AAPL.
- Matching engine — for each price tick, check triggered alerts. Use sorted structures (by threshold) to efficiently find crossed thresholds.
- DB design: alerts table (indexed by symbol), users table, notification log
- Streaming architecture: price feed → Kafka → matching workers (partitioned by symbol) → notification service
- Deep dive on trade-offs — accuracy vs latency, at-least-once vs exactly-once delivery, handling duplicate alerts.
- High-volume data — Uber cares about this. Discuss Spark/Flink for stream processing, windowing, and aggregation.
Follow-ups
- How do you avoid sending duplicate notifications when a price oscillates around the threshold?
- How do you handle a user with 10,000 alerts on the same stock?
- How would you support "% change over last hour" conditions (needs windowed state)?
- How do you scale the matching engine when one stock (e.g., during a crash) gets millions of updates?
- Push vs Pull for delivering the final notification to the user's device — which and why?