System design interviews are open-ended by design. The strongest candidates do not know more components — they follow a clear structure, make assumptions explicit and explain trade-offs.
Requirements before boxes
Separate functional requirements (what the system does) from non-functional ones (scale, latency, availability, consistency). Agree on what is out of scope.
- Who are the users and what are the core actions?
- How many users and requests per second?
- Read-heavy or write-heavy?
- What consistency does each action need?
Back-of-the-envelope estimates
Rough numbers guide design choices. Estimate requests per second, storage per year and bandwidth. Round aggressively — the goal is order of magnitude.
A simple end-to-end design
Draw the smallest design that works: clients, load balancer, stateless services, a primary database. Define the main APIs and the data model before adding caches or queues.
Deep dives where it matters
Let the requirements choose the deep dives. A feed needs fan-out strategy; a payment flow needs idempotency and strong consistency; a chat system needs connection management and ordering.
- Caching and invalidation
- Partitioning and replication
- Asynchronous processing with queues
- Rate limiting and abuse prevention
Close with trade-offs and failure modes
Summarise what you optimised for and what you gave up. Explain what happens when a component fails and how you would detect it with monitoring and alerts.