Skip to content
Commitwise
Menu
System Design

How System Design Interviews Work

What happens in a system design interview, what interviewers score at junior and senior level, and a step-by-step method for requirements, estimates, the big picture and deep dives that works for any question.

beginner

The core idea with one simple example.Step by step, with more examples and exercises.A cheat sheet: key APIs, gotchas and trade-offs.Internals, trade-offs and production pitfalls.

“Design Instagram.” You have 45 minutes, a whiteboard, and an interviewer who says almost nothing. Many candidates start drawing boxes in the first minute, and twenty minutes later they’re defending a Kafka cluster for a problem nobody defined. The question isn’t really “design Instagram”. It’s “show me how you think when a problem is too big to solve completely”, and that has a method.

New to some of these? Open what you need, or skip ahead.

Basics:What are clients and servers?

A server is a computer (usually many of them) that runs your backend: it stores data and answers requests. A client is whatever sends the requests: your mobile app, a website, another server.

Big systems put many identical servers behind one address, with a load balancer in front that spreads requests between them. Data lives in a database, and frequently used data is often kept in a fast cache (in memory) so the database isn’t asked every time.

Basics:What are databases, tables and SQL?

A database stores an app’s data so it survives restarts and can be searched quickly. A relational database (PostgreSQL, MySQL) keeps data in tables: rows (one per book, user or order) and columns (id, title, year).

You talk to it with SQL: SELECT title FROM books WHERE year > 2000 reads, INSERT, UPDATE and DELETE change data. Rows refer to other tables through foreign keys (book.author_id points to a row in author), and indexes make lookups by a column fast.

Basics:What is an API?

An API (application programming interface) is the set of operations a system offers to other programs. In app development it usually means a web API: a server with URLs your app calls to read and change data, like GET /api/products to list products.

The API is a contract: the app relies on its URLs, fields and status codes. Changing them carelessly breaks apps that are already installed on people’s phones.

Basics:What is a cache?

A cache keeps a copy of data somewhere faster to reach than its original source. Instead of asking the database for the same popular product 1,000 times a second, the server keeps it in memory (or in a cache server like Redis) and answers from there.

Two questions come with every cache: how long may a copy be used before it might be out of date (its time to live, or TTL), and what happens when the original changes (the copy must be removed or updated).

Part Not started

What the interview really tests

Imagine asking an architect to “design a house”. A good one doesn’t start drawing walls. They ask: for how many people? What budget? One floor or two? Is there a slope? Only then do they sketch, and when you ask “why is the kitchen here?”, they have a reason.

A system design interview checks the same thing. There’s no single right answer, and nobody expects you to build Instagram in 45 minutes. The interviewer wants to see that you can turn a vague request into a clear problem, sketch a reasonable solution, and explain your choices.

The interview is a proxy for one question: would I trust this person to lead the design of something ambiguous? That’s why the diagram matters less than the path to it. At senior level, interviewers look for you to drive: scope without being asked, quantify, pick the two or three areas where the design is actually hard, and argue trade-offs with numbers and failure modes. Covering every box shallowly reads as junior; going deep on the right box reads as senior.

What interviewers score

AreaJunior / midSenior
ScopingAsks clarifying questions, lists featuresDrives scope, states assumptions, cuts features on purpose
EstimationRough numbers, read vs write ratioUses numbers to make decisions (fits on one machine? needs sharding?)
DesignA working high-level design with standard partsData model and access patterns drive the choices
DepthExplains one component well when askedPicks the hard parts and goes deep unprompted
Trade-offsKnows there are optionsCompares options by consistency, latency, cost and failure modes
CommunicationThinks aloud, accepts hintsStructures the session, checks in, adapts to the interviewer

The six steps

  1. Requirements (about 5 min): what must it do, for how many users, how fast, how reliable?
  2. Estimates (about 5 min): requests per second, storage, read vs write. What do the numbers tell you?
  3. API and data model (about 5 min): the main endpoints and the main tables or records.
  4. High-level design (about 10 min): the boxes and arrows that handle the main use cases end to end.
  5. Deep dives (about 15 min): the one to three parts that are actually hard for this problem.
  6. Wrap-up (about 5 min): bottlenecks, failure cases, what you’d do with more time.

The times are a guide, not a rule. What matters is the order: you can’t design well before you know the requirements, and you can’t go deep before the whole thing works end to end. If the interviewer pulls you into a topic early, follow them; they’re telling you what they want to see.

How it feels from the other side

Interviewers usually have a short list of things they hope you’ll bring up for each question (for a URL shortener: generating unique codes, caching redirects, read-heavy traffic). They give hints when you’re stuck, and taking a hint well counts in your favor. Silence is the hardest thing for them to score, so think aloud: “I’m considering two options here, let me compare them” is far better than thirty seconds of quiet drawing.

It’s also fine to say “I don’t know how X works internally, but I’d expect it to behave like this, and I’d verify it”. Making things up is the one thing that reliably costs points.

What separates the levels

  • Mid: a correct design, prompted depth, textbook trade-offs.
  • Senior: the candidate sets the agenda (“the interesting parts here are fan-out and hot keys; I’ll design the baseline quickly and spend most of our time there”), quantifies, and names failure modes before being asked.
  • Staff: also reasons about evolution and organization: migration from the current system, cost at scale, which team owns what, what to build vs buy, and what to measure after launch.

Many companies calibrate the same question across levels; the bar moves, not the prompt. Ask early, “Is there anything specific you’d like me to focus on?”, and adjust.

  • The diagram is a by-product; the signal is scoping, quantified decisions, depth on the hard parts and trade-offs with failure modes.
  • Seniors drive: state assumptions, cut scope, announce where they’ll go deep, check in with the interviewer.
  • Six steps, roughly 5 / 5 / 5 / 10 / 15 / 5 minutes: requirements, estimates, API and data model, high-level design, deep dives, wrap-up.
  • Covering every box shallowly reads as junior. Going deep on the right two or three areas reads as senior.

Check this part

  1. What is the interviewer mainly looking for?

  2. What comes first in the six steps?

  3. You have 45 minutes. What reads as senior?

  4. The interviewer pulls you into caching after five minutes. What do you do?

A 45–60 minute conversation about an open-ended problem. Interviewers score how you scope, structure, justify trade-offs and communicate, not a correct diagram. Follow the same six steps every time and budget your minutes.

Part Not started

Requirements and estimates

Ask before you draw

Requirements come in two kinds:

Good questions for almost any problem:

Ask aboutExample
Users and scaleHow many daily active users? How many posts per day?
The main use casesWhich two or three features matter most? What can we leave out?
Reads vs writesDo people mostly read (a feed) or mostly write (a logging system)?
SpeedHow fast should the main screen load?
FreshnessIs it OK if someone sees an update a few seconds late?
ReliabilityWhat’s worse: showing old data, or showing an error?

Then write the answers down where the interviewer can see them, and agree on a small scope: “So: posting photos and a home feed, 10 million daily users, the feed should load in under 200 ms, and a few seconds of delay is fine. Comments, search and ads are out of scope.” Everything after that refers back to this list.

Drive this, don’t interview the interviewer: propose assumptions and let them correct you (“I’ll assume 100M DAU, read-heavy at roughly 100:1, p99 feed latency under 300 ms, eventual consistency for feed contents, and 99.95% availability; anything you’d change?”). Non-functional requirements are where the design actually comes from: consistency and latency targets decide caching, replication and sync vs async; durability decides storage; the read/write ratio decides almost everything else.

Name the requirements that conflict, because that’s where trade-offs live: strong consistency vs low latency across regions, freshness vs fan-out cost, availability vs correctness for payments.

Back-of-the-envelope estimates

You don’t need exact numbers, only the size of the problem. A few round facts make it fast:

  • A day has about 86,400 seconds; use 100,000 (10⁵).
  • Per day ÷ 100,000 = per second. Peak is usually 2 to 5 times the average.
  • 1 KB = 10³ bytes, 1 MB = 10⁶, 1 GB = 10⁹, 1 TB = 10¹².
10 million daily users, each opens the feed 10 times a day
  → 100 million feed loads per day ÷ 100,000 ≈ 1,000 per second, peak ≈ 3,000

1 in 10 users posts one photo a day
  → 1 million uploads per day ≈ 10 per second

Reads : writes ≈ 1,000 : 10 = 100 : 1  → read-heavy: caching and precomputed feeds pay off

Photos: 1 million × 2 MB ≈ 2 TB per day ≈ 730 TB per year
  → doesn't fit in a database: object storage (like S3) plus a CDN

The last line of each estimate is the important one: what does the number mean? “1,000 reads per second” alone isn’t interesting. “Read-heavy, so I’ll cache feeds” and “hundreds of terabytes, so photos go to object storage, not the database” are design decisions you can now defend.

Predict the output

A chat app has 50 million daily users, and each sends 40 messages a day. Roughly how many messages per second is that on average?

Practice: estimate a ride-sharing app

  1. Scale. 5 million rides per day. Drivers send their location every 4 seconds while online; assume 1 million drivers online at peak.
  2. Location writes. 1,000,000 ÷ 4 = 250,000 updates per second at peak. That’s the dominant load, far above everything else.
  3. Rides. 5 million per day ÷ 100,000 = 50 per second on average: small.
  4. Storage. A location update is about 100 bytes. Keeping only the latest position per driver: 1 million × 100 bytes = 100 MB, which fits in memory. Keeping every update for a day: 250,000 × 100 bytes × 86,400 s ≈ 2 TB per day, so history goes to cheap storage, not the hot path.
  5. Conclusion. The hard part is a high-rate stream of small writes and “find drivers near me” queries, not the rides themselves. That’s where the deep dive goes.

Numbers worth knowing

Orders of magnitude, not benchmarks; quote them as such.

OperationRoughly
Main memory read~100 ns
SSD random read~100 µs
Round trip inside a data center~0.5 ms
Redis GET from an app server< 1 ms
Indexed database lookup1–10 ms
Round trip Europe ↔ US East~80–100 ms
One cache node~100,000 simple ops/s
One relational database primarythousands to low tens of thousands of simple queries/s
AvailabilityDowntime per month
99%~7 h
99.9%~43 min
99.99%~4 min

Two quick rules: dependencies called in series multiply their availability, and redundant replicas multiply their unavailability. A service that needs three 99.9% dependencies is at most ~99.7%; two independent 99% replicas give ~99.99%.

  • Propose assumptions instead of asking open questions; get agreement on DAU, read/write ratio, latency (p99), consistency, availability, and what’s out of scope.
  • Non-functional requirements drive the design; name the conflicting ones (consistency vs latency, freshness vs fan-out cost).
  • Estimates: per day ÷ 10⁵ = per second, peak 2–5×, storage per year with replication. Always state the consequence: fits in memory? one primary enough? object storage?
  • Availability: series dependencies multiply availability; redundant replicas multiply unavailability. 99.9% ≈ 43 min/month.

Check this part

  1. "The feed should load in under 200 ms" is what kind of requirement?

  2. 10 million uploads per day is roughly how many per second?

  3. An endpoint calls three services in series, each 99.9% available. Its best possible availability is about…

  4. What should every estimate end with?

Split requirements into functional (features) and non-functional (scale, latency, availability, consistency), and agree on a small scope. Estimate per-second traffic, peak and storage with round numbers, and state what the numbers mean for the design.

Part Not started

The big picture, then the hard parts

API and data first

Before boxes, write the two or three main endpoints and the main records. It takes three minutes and keeps the design honest:

POST /photos              { caption, imageUploadId }        → { photoId }
GET  /feed?cursor=…       → { items: [ { photoId, url, author, caption } ], nextCursor }
POST /users/{id}/follow

User   (id, name, …)
Photo  (id, authorId, storageKey, caption, createdAt)
Follow (followerId, followeeId)

The building blocks

Most designs are assembled from the same parts. Tap a box to see what it’s for:

Common building blocks

imagesAPIreaduploadasyncMobile / webCDNstatic filesLoad balancerApp serversstatelessCacheRedisDatabaseObject storagephotos, filesQueueWorkers

Tap a box to see what it does.

Walk through each main use case on your diagram, out loud: “A user uploads a photo: the app sends it to object storage, the server saves a Photo row, and drops a ‘new photo’ job on the queueMessage queueA buffer where one part of a system leaves work as messages and another part picks them up later.Open in glossary →. A worker creates thumbnails and adds the photo to followers’ feeds.” If you can’t trace a use case through your boxes, a box is missing.

Deep dives and trade-offs

Once the whole thing works on paper, pick the parts that are hard for this problem and go deeper: for a feed, how feeds are built for users with millions of followers; for chat, delivering messages in order to offline phones; for a URL shortener, generating unique short codes.

Explain every choice as a trade-off: what you gain, what you give up, and why that’s right for these requirements. “I’ll use a cache, because we’re read-heavy; the cost is that a feed can be a few seconds stale, which we agreed is fine” is the sentence interviewers are waiting for.

Choose deep dives by risk: where the naive design breaks at the estimated scale (hot keys, fan-out, write amplification, cross-shard queries), where correctness is subtle (ordering, idempotency, exactly-once illusions), or where cost explodes (storage growth, egress). Announce the choice and why, then go to mechanisms: data layout and partition keys, consistency model, failure handling (retries, timeouts, backpressure, what happens during a partial outage), and how you’d observe it in production.

Practice

Spot the bugA candidate's first two minutes

Tap the line with the bug.

Interviewer: Design a notification system.
Candidate: OK! I'd put Kafka in the middle, with Cassandra for storage.
Candidate: Producers publish events, consumers send push and email.
Candidate: We can shard Cassandra by user id to scale it.
Interviewer: How many notifications are we talking about?
Candidate: Probably a lot, so Kafka is a good choice.

Exerciseeasy

Scope and estimate a food delivery tracker

“Design the feature that shows customers where their food delivery is, live on a map.”

Write down, in five minutes: three functional requirements, three non-functional requirements, the out-of-scope list, and an estimate of location updates per second. Assume 2 million orders a day, an average delivery of 30 minutes, couriers sending their position every 5 seconds, and that dinner peak is 3 times the average.

›

How many deliveries are in progress at the same time on average? 2 million orders spread over 100,000 seconds, each lasting 1,800 seconds.

›

Each active delivery sends one update every 5 seconds. Divide the number of active deliveries by 5, then multiply by 3 for the peak.

SolutionTry it yourself first

Functional: a courier’s app sends its location; the customer sees the courier’s position on a map, updating live; the customer sees an estimated arrival time.

Non-functional: the customer’s map is at most ~5–10 seconds behind; losing a single location update is fine (the next one replaces it); the tracking screen must keep working during peak; location data is private and deleted after delivery.

Out of scope: ordering, payments, restaurant screens, courier assignment, route optimization.

Estimate:

Orders: 2,000,000 per day ÷ 100,000 s ≈ 20 new orders per second
Active at once: 20 per second × 1,800 s per delivery ≈ 36,000 deliveries
Updates: 36,000 ÷ 5 s ≈ 7,200 per second on average, × 3 ≈ 22,000 per second at peak
Latest positions: 36,000 × 3 (peak) × ~100 bytes ≈ 11 MB → fits in memory easily

What it means: tens of thousands of tiny writes per second, but only the latest position matters and it fits in memory. So the hot path is an in-memory store (like Redis) keyed by delivery, with a push channel (WebSocket or server-sent events) to the customer’s app, instead of writing every update to the main database.

Wrap-up that scores

Use the last five minutes deliberately: name the bottleneck at 10× the estimated load, the riskiest failure mode and how the system degrades (serve stale feed vs error), what you’d monitor (p99 latency, queue lag, error budget), and what you’d build differently with another month. That shows you know the design is a starting point.

Production puzzles

Predict the output

A feed endpoint calls the user service, the graph service and the post service in sequence, each 99.9% available. You add a second, independent replica set for the post service only. What's the endpoint's best possible availability now?

Spot the bugA storage estimate that sails through review

Tap the line with the bug.

Messages: 2 billion per day, 200 bytes each
Per day: 2 × 10^9 × 200 B = 400 GB
Per year: 400 GB × 365 ≈ 146 TB
Our cluster has 200 TB of disk, so we're fine for a year.
Writes: 2 × 10^9 / 10^5 = 20,000 per second, well within capacity.

Exercisemedium

Run a mock: a notification system

Give yourself 45 minutes, a timer and a blank page. Prompt: “Design a notification system that sends push, email and SMS for a company with 50 million users and many internal teams.” Afterwards, check your answer against the outline in the solution: not the boxes, but whether you hit each step and chose good deep dives.

›

Requirements to pin down: priorities (a login code vs a marketing email), user preferences and quiet hours, rate limits per user, delivery guarantees, and who sends (dozens of internal teams through one API).

›

The hard parts are usually: not losing or duplicating important notifications across retries and provider outages, fairness between urgent and bulk traffic, and per-user preferences and rate limits at scale.

SolutionTry it yourself first

A strong session, step by step:

  1. Requirements (5 min). Channels: push, email, SMS. Senders: internal services through one API. Priorities: transactional (OTP, payment) vs marketing. User preferences, opt-outs and quiet hours. At-least-once delivery with deduplication, so users see each notification once. Out of scope: templates editor, analytics dashboards.
  2. Estimates (5 min). 50M users × ~5 notifications a day = 250M/day ≈ 2,500/s, peaks of 10–20× during marketing campaigns. SMS is the expensive channel; push is most of the volume.
  3. API and data (5 min). POST /notifications { userId, type, priority, payload, idempotencyKey }; preferences per user and type; a delivery log keyed by idempotency key.
  4. High-level (10 min). API → validation and preference check → per-priority queues → channel workers (push, email, SMS) → providers (APNs/FCM, email provider, SMS provider), with a delivery log and retries with backoff.
  5. Deep dives (15 min), chosen and announced:
    • Priority isolation: separate queues and worker pools, so a 20M-recipient campaign can’t delay a login code.
    • Exactly-once for the user: idempotency keys from senders, dedup in the delivery log before sending, provider-level idempotency where available; accept that the network makes “exactly once” an at-least-once plus dedup.
    • Provider failures: timeouts, circuit breakers, failover to a second SMS provider, and a dead-letter queue with alerts.
  6. Wrap-up (5 min). Bottleneck at 10×: the preference lookup (cache it); risk: a provider outage during a campaign; metrics: queue lag per priority, send success per provider, cost per channel.

If you spent more than ten minutes on boxes before the first deep dive, or never mentioned priorities, that’s the habit to practice. The next lessons in this section go through full case studies with this structure.

  • Write the API and core entities before boxes; they expose access patterns and partition keys.
  • Baseline from standard blocks (LB, stateless servers, cache, DB with replicas and shards, object storage + CDN, queue + workers), then trace every use case through it.
  • Choose deep dives by risk at the estimated scale: hot keys, fan-out, write amplification, ordering, idempotency, cost. Announce the choice.
  • Estimates must include replication, indexes, headroom and peak. Redundancy on one hop doesn’t fix a chain of series dependencies.
  • Wrap up with the 10× bottleneck, degradation strategy and what you’d monitor.

Check this part

  1. When should you name specific technologies like Kafka or Cassandra?

  2. What makes an explanation a trade-off?

  3. A storage estimate says 146 TB per year on a 200 TB cluster. What's most likely missing?

  4. How do you choose deep dives?

Sketch the main flows end to end with standard building blocks, then go deep on the one to three hard parts. Explain every choice as a trade-off, and finish with bottlenecks and failure cases.

Key takeaways

  • The interview scores how you think: scoping, structure, trade-offs and communication, not one correct diagram.
  • Follow six steps: requirements, estimates, API and data, high-level design, deep dives, wrap-up.
  • Split requirements into functional and non-functional, agree on a small scope, and write it down.
  • Estimate with round numbers (per day ÷ 100,000 = per second) and always say what the number means.
  • Name technologies only with a reason, and explain each choice as a trade-off.
  • Drive the session: propose assumptions, cut scope, announce where you’ll go deep, and check in.
  • Non-functional requirements and the read/write ratio drive the design; name the ones that conflict.
  • Estimates need replication, overhead, headroom and peak, and must end in a decision.
  • Spend most of the time on the hard parts, chosen by risk; wrap up with the 10× bottleneck and failure modes.

Finished this page?Nice work, this page is complete!

Mark it as done to track your progress. It's saved in this browser, no account needed.

Its cards are now in your Bites review ⚡
Esc

Type to search the whole site.