System Design Interviews
How to Approach System Design
The interview question is: "Design Instagram's photo feed." Forty-five minutes start now. If you jump straight into microservices and global shards, you usually design the wrong product.
A strong answer is a guided conversation: agree what you are solving, estimate scale, draw the simplest useful architecture, then go deeper where the design is most likely to break.
First 20 minutes
Clarify scope
Posting vs feed reads? What is out of scope?
Rough math
, storage, and a latency target.
Sketch paths
Draw the read path and write path first.
Pick the risk
Deep dive where the design breaks first.
What actually happens in the conversation
You begin by asking whether feed reads dominate, whether likes need strong correctness, and what can wait. That turns a vague product into a scoped surface and an explicit consistency choice: often for likes while the core post write stays durable.
Next come estimates: daily users x actions → , plus storage growth and a latency budget. Those numbers decide whether a or is justified, and whether celebrity will become the bottleneck.
Only then do you deepen: pick the riskiest path, state trade-offs, and ask where the interviewer wants more depth. The frameworks below are training wheels until this pacing feels natural.
Try it: pace a 45-minute design conversation
Treat the round as checkpoints with artifacts. Advance time, mark what you would have on the whiteboard, and notice when you are ahead or behind the timeline used on this page.
- Simulated minute
- 0
- Checkpoints done
- 0 / 5
- Next focus
- Clarify scope
Clarify scope
By 5mUsers, must-have features, latency and freshness promises.
Estimate load
By 10mQPS, storage, bandwidth, and peak multiplier on the board.
Draw paths
By 20mRead, write, and async paths with named components.
Deep dive
By 35mOne or two bottlenecks with data structures and failure behavior.
Trade-offs + ops
By 45mAlternatives rejected, metrics, retries, and degradation plan.
Advance simulated time and mark checkpoints complete. Strong pacing leaves visible artifacts before the minute marker, not after. Next marker: Clarify scope by minute 5.
Drive, then invite depth. Finish clarifying and estimating before you add every trendy store. When the interviewer redirects, update scope and revisit estimates instead of erasing the whole diagram.
Progression guide
Beginner to advanced: what changes
Beginners often skip requirements or estimates and jump to queues and orchestration. Slow down: spend the first minutes agreeing what you are building.
Intermediate candidates produce a sensible diagram and basic math; they start naming failure modes when asked.
Advanced candidates drive pacing, challenge assumptions, compare alternatives without being asked, and tie choices to operational concerns (deployments, monitoring, cost).
With that pacing in mind, the card below is one reset checklist: how to choose the next move, what a complete answer looks like, and how to recover when you stall.
Core method: choose, size, recover
Turn every broad requirement into an observable behavior before choosing infrastructure. “Reliable notifications” could mean that a job is never lost after acceptance, that a provider accepts it within five seconds, or that a user actually sees it. These promises require different evidence and may depend on systems you do not control. Agree which boundary the system guarantees, then describe later states separately.
How to choose your next move
1. Spend the first minutes on agreement. Requirements prevent over-building the wrong product.
2. Use numbers before fancy components. Let load and latency budgets force , , or partition choices (see Numbers to know).
3. Recover with a sequence. Use the grounded sequence below when you stall. Rule of thumb: if lost, return to the write path, then the read path, and see which drives scale.
The systematic approach
A typical round lasts about 45 minutes. Treat it as a collaborative design review with a colleague who might steer you with hints. Interviewers measure communication, requirements discovery, sound component choices, quantitative reasoning, trade-offs, and depth on a few areas, not encyclopedic breadth.
Minimum viable answer
If you feel lost, aim for this small but complete answer once (and cross-ref it later instead of restating):
5 components
Client, API, database, cache, and queue cover most product shapes.
3 estimates
QPS, yearly storage, and a p95 latency target force sizing.
2 trade-offs
Cache freshness vs speed; queue delay vs reliability under spikes.
1 deep dive
Pick the riskiest path and explain failure handling out loud.
The sequence that keeps answers grounded
A clean answer moves from user behavior to numbers to data movement: API → data model → capacity → bottleneck → trade-off. That order prevents diagram-first answers. Recovery phrase: "Let me anchor this in the write path, then I will check the read path and see which one drives scale."
API
What user action enters? What must stay sync vs async?
Data model
Which entities are stored, indexed, and retained over time?
Capacity
QPS, storage, bandwidth, p95, and peak multiplier (Numbers to know).
Bottleneck
Which tier saturates first: DB, cache, queue, or network?
Trade-off
What do we gain, accept, and monitor after the choice?
The map below turns that method into checkpoints you can say out loud as you drive the round.
Interview flow
Conversation map: drive, then invite depth
Treat the round as a sequence of checkpoints. At each checkpoint, say what you are assuming and ask whether the interviewer wants to adjust scope. This keeps you from over-building the wrong system.
Good signposting
"I will start with core posting and feed reads, assume for likes, and revisit payments-like correctness if needed."
Common mistake
Solving every possible feature at once, then running out of time before explaining bottlenecks or failures.
A strong round is conversational, not a monologue. This abbreviated transcript shows how to keep control while still adapting when the interviewer narrows scope.
Mock interview transcript: clarifications and course correction
Candidate
Before I draw anything, I want to scope the core path. Should I optimize for creating posts, reading the feed, or both equally?
Interviewer
Assume feed reads dominate. Make it global later if you have time.
Candidate
Great. I will target feed reads first, assume eventual consistency for likes, and come back to global writes only if the core read path is stable.
Candidate
For estimates, I will assume 50M daily active users, 20 feed opens per day, and a 5x peak multiplier. That makes the read path the main scaling pressure.
Interviewer
What if a celebrity posts and 10M followers refresh at once?
Candidate
That changes the bottleneck from normal fan-out to hot-key and queue pressure. I would switch to hybrid fan-out: precompute for typical users, but pull on read for celebrity accounts and cache ranked windows.
Interviewer
What would you monitor first after launch?
Candidate
Feed p99 latency, cache hit ratio, queue age for fan-out jobs, and stale-read complaints. Those tell me whether the chosen trade-off is still working.
Candidate
If you want, I can now deep dive into celebrity handling or stay on data-model and consistency choices.
Why this scores well: the candidate keeps stating assumptions, reacts to hints, changes the architecture when the bottleneck changes, and asks permission before diving deeper.
Think of the interview as seven short phases. If one phase runs long, steal time from detailed design later, not from clarifying the problem. Say out loud: "I'll spend ~5 minutes on requirements, then move to estimates": that scores well and keeps you honest. If you are 10 minutes in and still on requirements, you are behind; a perfect diagram with no deep dive is a weak signal.
Time management: the 45-minute breakdown
| Phase | Time | What to Do |
|---|---|---|
| 1. Requirements | 5 min | Clarify scope, ask questions |
| 2. Estimation | 5 min | Back-of-envelope math (QPS, storage) |
| 3. High-Level Design | 10 min | Draw architecture diagram |
| 4. API Design | 5 min | Define key endpoints |
| 5. Data Model | 5 min | Schema, database choice |
| 6. Deep Dive | 10 min | 2-3 critical components |
| 7. Bottlenecks & Scale | 5 min | Failure modes, scaling strategy |
The artifact timeline pairs with that table: by each minute marker, something visible should exist on the board.
45-minute artifacts
Artifact timeline
By each time marker, something visible should exist in your answer. This prevents long silent thinking.
5 minutes
Scope and non-functional requirements
10 minutes
QPS, storage, bandwidth estimates
20 minutes
Read and write path diagram
35 minutes
Deep dive on bottleneck
45 minutes
Trade-offs, failure handling, metrics
Capacity numbers for the worked examples sit here once. Cross-ref this section instead of repeating the math in every story.
Numbers to know
Notification system (write-heavy)
The example below assumes 10 billion notification records per day, including all recipients rather than only source events. Dividing by 86,400 gives about 115,741 records per second; a fivefold peak is about 578,704 per second. At an assumed 200 bytes per retained record, raw storage is 2 TB per day or 730 TB per year in decimal units. Replicas, indexes, message envelopes, and delivery attempts increase physical storage; shorter retention reduces it.
- ~500M users and ~10B notifications/day imply ~115K/sec average write throughput.
- Peak at 3-5x average reaches roughly 350K-580K/sec, so workers and queues must absorb spikes.
- ~730 TB/year of storage growth forces retention and wide-log planning early.
- Channel mix: push ~60% (~6B), email ~25% (~2.5B), SMS ~10% (~1B), in-app ~5% (~500M).
- Write-heavy needs a durable , horizontal workers, and per-channel rate limits.
Public article reader (read-heavy)
- 50M reads/day is about 580 average before applying a peak multiplier.
- With 5x peak and 95% cache/CDN hits, the database sees about 145 QPS at peak, not 2,900.
Walk through this notification design slowly once with a timer. You do not need vendor names: substitute "queue" and "delivery provider." The point is to see how requirements → math → components → deep dive stays coherent. Peak numbers are in Numbers to know. RESHADED (private mnemonic) lives in the toolkit wrap-up at the end.
Worked example: notification system (45 min)
Minutes 0-5: Requirements
Clarifying questions
- Which channels (push, SMS, email, in-app) matter so you size providers correctly?
- How many users and what daily volume so estimates drive the architecture?
- Real-time vs batched: what delay is acceptable per channel for product fit?
- Per-channel preferences and opt-out rules so you avoid unwanted spam?
Functional: send via push, SMS, email, and in-app; preferences per channel and type; history with read/unread; anti-spam rate limits.
Non-functional: latency targets such as push under ~5s and email under ~30s; high delivery with at-least-once to providers; dedupe so retries do not double-notify the inbox. Scale figures: see Numbers to know.
Minutes 5-10: Estimation
Convert daily volume to average and peak throughput, then storage growth. Architecture takeaway: write-heavy fan-out needs a durable queue, horizontal workers, and per-channel rate limits and batching (providers cap you before your cluster does). Full figures: Numbers to know.
Minutes 10-20: High-level architecture
Make acceptance durable: the API records the notification request and its delivery intent before returning an identifier. If recording state in a database and publishing to a queue are separate writes, a crash between them can leave a saved request with no queued job. A transactional outbox records the request and an outgoing event together; a relay publishes that event and can retry using its stable identifier. This is the concrete reason the write path needs more explanation than an arrow labeled “queue”.
Service/Event → Notification → Preference Check → Rate Limiter → Durable . Then per-channel workers: push → mobile provider; email → email provider; SMS → SMS provider; in-app → WebSocket / SSE (server-sent events).
- Preferences: fast read keyed by user so checks stay cheap.
- Notification log: wide storage for history and delivery status over time.
- Templates: localize and render copy per channel before provider handoff.
- Analytics: delivery funnel, experiments, and abuse signals after send attempts.
Minutes 20-35: Deep dive on reliability and deduplication
A deduplication marker is not proof that delivery completed. If a worker marks a message as processed and crashes before calling the provider, blindly skipping the retry loses the notification. If it calls the provider first and crashes before saving success, retrying can send a duplicate. Store an explicit processing state and recover abandoned attempts; use a stable provider idempotency key when the provider supports one. Without such support, reconcile ambiguous outcomes or explicitly accept possible duplicate delivery.
Retry policy also depends on the message’s useful lifetime. An expired one-time password should not be sent an hour later just because the retry schedule allows it. Include an expiry time, distinguish transient failures from invalid destinations, and move permanently failed or expired work to a visible terminal state. A dead-letter queue needs an owner and a replay policy, otherwise it merely hides undelivered work.
At-least-once delivery + dedupe at the worker
- Producer publishes each job with a stable
notification_idso retries stay identifiable. - Worker claims the stable identifier in durable processing state; a temporary lock coordinates concurrent attempts but does not mean delivery succeeded.
- If new: deliver to provider, persist "sent" state, then acknowledge the message.
- If the durable state is completed, return its recorded result and acknowledge the duplicate. If the attempt is incomplete, recover it according to the provider’s idempotency and reconciliation behavior.
- Ack only after durable side effects you care about (provider OK + DB write), not before.
Retry backoff: attempt 1 immediate; 2 ≈30s; 3 ≈2 min; 4 ≈15 min; 5 ≈1 hr then DLQ (dead-letter queue) / manual path.
Priority lanes: P0 security (minimal latency); P1 transactional receipts and OTPs (must land); P2 engagement likes and digests (can yield under load).
Minutes 35-45: Bottlenecks, scale, and monitoring
Queue depth alone does not show whether users are waiting too long. If workers process 20,000 messages per second, a backlog of 100,000 represents roughly five seconds of work only when new arrivals are ignored. With 18,000 new messages per second, net drainage is 2,000 per second and clearing the same backlog takes about 50 seconds. Measure oldest-message age alongside arrival rate, completion rate, and provider throttling to decide whether adding workers will actually help.
Third-party rate limits require adaptive batching and back-pressure. Monitor delivery latency p50/p95/p99, failure rate per channel, queue depth, and dedup hit rate. Graceful degradation: if SMS fails, queue and retry; show in-app fallback.
- Depth and age per queue or priority lane show whether workers keep up.
- Provider HTTP errors and throttle responses reveal external caps before your cluster.
- End-to-end latency from API accept to device receipt proves user experience.
After the write-heavy walkthrough, here is the complementary read-heavy path diagram (article reader). Math stays in Numbers to know.
Worked example
Short read-heavy worked example
Problem statement: design a public article reader. Reads dominate writes, so focus on hit ratio, CDN (content delivery network) edge copies, and invalidation. Peak math lives in Numbers to know.
CDN miss → Gateway → API → cache; cache miss → database. Hits short-circuit earlier.
The remaining pieces are interview toolkit: follow-ups, trade-off phrasing, level signals, anti-patterns, diagrams, templates, and how to handle unknowns.
Interview toolkit and wrap-up
RESHADED checklist
Private mnemonic (do not announce awkwardly): Requirements, Estimation, Storage schema, High-level design, API design, Detailed design, Evaluation, Distinctive features.
- R Requirements: Functional plus non-functional. Who are the users, what scale, what SLAs? Ask what must be sync vs delayed.
- E Estimation: QPS, storage, bandwidth. Use powers of 10; if writes dominate, justify queues and write-optimized stores.
- S Storage schema: Data model, SQL vs NoSQL, partitioning. Name hot access paths like "list posts by user."
- H High-level design: Clients, load balancer, servers, DB, cache, queues. Show where reads vs writes go first.
- A API design: Key endpoints with request/response. Keep verbs aligned with user stories such as GET /feed.
- D Detailed design: Deep dive into 2-3 stressed pieces (fan-out, ranking, dedupe, consistency), not everything.
- E Evaluation: Bottlenecks, failure modes, trade-offs at 10x scale. Mention queue lag, errors, and saturation metrics.
- D Distinctive features: Monitoring, A/B testing, graceful degradation. Tie extras to requirements such as idempotency for retries.
Handling "what if" follow-ups
- Scale: "Traffic 10x overnight?" Find the bottleneck (queue depth, workers, DB writes), then explain how each tier scales, including partitions and auto-scale on depth.
- Failure: "Database goes down?" Detect with health checks, mitigate via replica failover, recover by promote and queue replay; discuss blast radius.
- Trade-off: "Why a log-style queue?" State criteria (ordering, replay, throughput), compare options, justify, and acknowledge downsides.
- Deep dive: Trace one notification from API through queue, worker, provider, status update, and analytics; mention latency per hop.
STAR for trade-offs
State options ("SQL or NoSQL"). Trade-offs (ACID vs write scale). Argue from requirements (e.g. 100:1 reads plus complex queries). Risks and mitigations (shard by user_id at 50K writes/sec).
Practice phrases: "The trade-off here is between X and Y..." | "I'm choosing X because our requirement for Z..." | "The downside is... but we can mitigate..." | "An alternative would be... which would be better if..."
Interviewer expectations by level
- L4 / E4 (mid): Correct functional design, order-of-magnitude estimates, common blocks (LB, cache, DB), trade-offs when asked; needs hints for deep dives.
- L5 / E5 (senior): Drives with minimal guidance; estimates shape architecture; proactively names bottlenecks; 2-3 unprompted trade-offs; deep dives two components.
- L6+ / E6+ (staff+): Org boundaries, ops (deploy, monitor, on-call), evolution and migration, cost/compliance/multi-region; can teach the interviewer something new.
Anti-patterns that fail interviews
| Anti-Pattern | Why It Fails | Fix |
|---|---|---|
| "Resume Reciter" | Recites memorized designs without understanding | Reason from first principles instead |
| "Buzzword Bingo" | Drops names for queues or caches without justification | Explain WHY you chose each component |
| "Premature Optimizer" | Jumps to sharding before establishing need | Start simple, scale when numbers demand it |
| "Silent Architect" | Draws for 10 minutes in complete silence | Think out loud, narrate every decision |
| "Feature Creep" | Adds every feature instead of going deep on a few | Scope tightly, then go deep on 2-3 components |
| "One-Way-Door" | Asserts one solution with no alternatives discussed | Always present at least 2 options, then choose |
Drawing diagrams that communicate
Do: label every component and arrow; show data-flow direction; annotate with QPS and latency; group related pieces; start simple then add detail; use colors or line styles for paths.Don't: leave unlabeled boxes; draw spaghetti crossings; dump everything at once; omit DB and cache; draw in silence; use vague names like "Service A."
Reusable interview templates
Clarifying questions
Estimate sheet
API and data sketch
Risk table
Deep-dive selector
Deep-dive chooser
| Dominant risk | Deep dive here | Metric to mention |
|---|---|---|
| Read latency | Cache/CDN strategy and invalidation | p95 latency, hit ratio |
| Write throughput | Partition key and batching | write QPS, hot partitions |
| Slow side effects | Queue semantics and worker retries | queue age, retry rate |
| Correctness | Transactions, idempotency, consistency model | duplicate rate, stale-read rate |
| Realtime experience | WebSocket or event stream path | connection count, fanout latency |
How to handle "I don't know"
- Avoid: bare "I don't know" silence, or a confident but invented answer with no reasoning.
- Better: "I'm not sure about the exact implementation, but my intuition is X because Y. I'd want to verify this before building it."
- Better: "I haven't used that storage engine directly, but if it uses LSM trees, I'd expect write-optimized performance with periodic merges."
- Better: "That's a great question. Let me think about what constraints would guide this decision..." then reason out loud.
Takeaway
- Budget time: 5-5-10-5-5-10-5 minutes across the seven phases above.
- Use RESHADED privately as a checklist, then deep dive where risk is highest.
- Walk through real designs: notification system and the read-heavy article path on this page.
- Handle follow-ups: scale → bottleneck; failure → detect/mitigate/recover; trade-offs → STAR.
- Draw clearly: label everything, annotate with numbers, narrate as you draw.
- Handle unknowns: reason out loud, state assumptions, show your thinking process.
Primary sources
- Google SRE: Engaging with Production: production-first design reasoning.
- AWS Well-Architected Framework: structured trade-off questions.
- RFC 2119: Key words for requirements: precise requirement language.
Practice and further reading
Use these exercises to connect the lesson to a design decision. State your assumptions, trace what happens to one request, and explain the rule that must remain true even during a failure. That rule is the design's correctness invariant.
Focus for this lesson: Use a repeatable interview loop: requirements, estimates, API/data model, high-level flow, bottlenecks, failure handling, and trade-off recap.
Explain the decision
How do you keep a 45-minute design answer from becoming a technology tour?
Read the reasoning
Time-box the phases, maintain a requirements/invariants sidebar, and deepen only the bottleneck or correctness path the interviewer selects.
Apply it to a production scenario
Your first capacity estimate shows the write database cannot meet peak load. What changes?
Read one approach
Revisit access patterns, batching, partition ownership, write amplification, and whether strong consistency is needed on every field before selecting a different store.
Work through the numbers
Budget a 200 ms p99 endpoint across gateway, application, two dependencies, and network reserve.
Read the worked calculation
One explicit split is 15 + 35 + 50 + 50 + 50 ms reserve = 200 ms; parallel dependencies use the slower branch, not their sum.
Reason through a failure
What should a final design recap prove?
Read the recovery reasoning
That stated invariants survive timeout, retry, overload, dependency loss, deploy rollback, and recovery, with a signal and owner for each guardrail.
Sources and further study
Continue with Trade-offs in System Design.