Overview
It is 10:00 and BoxOffice opens the sale of a stadium show: two million fans, sixty thousand seats. Over the semester you built every piece needed to survive that morning β a CDN and a WAF at the edge, stateless services behind a load balancer, a cache, a database that never sells a seat twice, a queue, a payment integration, observability, a load test that found the knee. This class puts the pieces together the way an interviewer asks for them: a one-sentence prompt, a blank whiteboard and 45 minutes.
The twelve case studies below are the classic system-design interview problems. They are not twelve unrelated systems: they are the same few ideas β cache the hot reads, take slow work off the critical path, choose a partition key, make retries safe, protect the one resource that cannot scale β combined in different proportions. Studying them is how the vocabulary of the course becomes a reflex.
The story so far
Chapter 16, the last of the story of the course. Every earlier chapter added one box to BoxOffice because a number asked for it, and class 15 proved that the boxes hold together at 10:00. The next system will not be BoxOffice: it will be a feed, a chat, a ride app β the same blocks with other numbers. This class answers: can you rebuild that reasoning, number by number, for a system you have never seen, in 45 minutes?
Learning objectives
By the end of this class you should be able to:
- Apply the interview framework of class 1 to an unseen problem within 45 minutes: clarify, estimate, API and data model, high-level design, deep dives, bottlenecks and wrap-up.
- Estimate the load of a system from a few assumptions and derive design decisions from the numbers.
- Compose palette components (edge, compute, storage, messaging, observability, AI) into a design and justify each one.
- Analyze a design for bottlenecks and failure modes and defend its trade-offs out loud.
- Validate a design under load in the System Design Playground and explain what the metrics show.
- Evaluate your own answer against a junior / mid / senior rubric.
Roadmap
- This overview β how to study a case, how to use the playground, the cases at a glance and the patterns that repeat.
- URL shortener β ID generation, base62, caching hot links, analytics off the critical path.
- Rate limiter β token bucket and sliding windows, atomic counters, fail-open vs. fail-closed.
- Distributed cache β consistent hashing, eviction, replication, hot keys.
- Search autocomplete β trie with top-k, offline aggregation, serving from memory.
- Notification system β channels, queues, retries, deduplication, providers.
- News feed β fan-out on write vs. read, celebrities, timeline cache, ranking.
- Chat β WebSockets, routing between gateways, ordering, offline delivery, presence.
- Ride sharing β location ingestion, geospatial indexes, matching without double assignment.
- Video streaming β uploads, transcoding pipeline, adaptive bitrate, CDN economics.
- Payment system β idempotency, double-entry ledger, PSP integration, reconciliation.
- Ticketing β the BoxOffice flash sale β the flagship: waiting room, seat holds, checkout.
- AI assistant β RAG, LLM gateway, agents with tools, guardrails and evals.
- Quiz β check your understanding.
Slides
Click the slides and use β β to move through them; F goes full screen and P opens the presenter view, with the notes. Open the slides in a new tab
How to study a case
Every case page follows the interview framework of class 1, section by section, so you can rehearse the order until it is automatic. The timing below is for a 45-minute interview; the case pages use the same numbering.
| # | Step | Minutes | What you produce | Typical mistake |
|---|---|---|---|---|
| 1 | Clarify the requirements | 5 | Functional list, non-functional targets with numbers, out of scope | Designing before knowing whether it is 1 k or 1 M users |
| 2 | Estimate | 5 | QPS (average and peak), storage, bandwidth, memory β and one sentence on what they imply | Computing numbers and never using them |
| 3 | API and data model | 5β7 | A handful of endpoints, main entities, the store for each and why | Twenty endpoints, no idempotency, no pagination |
| 4 | High-level design | 10 | One diagram with the read path and the write path | Boxes without data flows; every component "because big systems have it" |
| 5 | Deep dives | 10β15 | Two or three hard parts solved with alternatives and a choice | Going deep on the easy part |
| 6 | Bottlenecks, failure modes, trade-offs | 5 | What breaks first, what happens when X dies, what you gave up | "It scales horizontally" with no evidence |
| 7 | Wrap-up | 2β3 | Summary, what you would do next, how you would measure it | Running out of time mid-sentence |
The ten sections of each case page map onto these steps: requirements (1), estimates (2), API and data model (3), high-level design (4), deep dives (5), bottlenecks and trade-offs (6), and then three study aids β Try it in the playground, Follow-up questions and a self-assessment rubric.
A study method that works
- Attempt first. Read only the prompt (the quote at the top of the page). Set a timer for 40 minutes and solve it on paper or on the playground canvas, out loud, as if an interviewer were there.
- Compare section by section. Open the page and compare your requirements, numbers, API, diagram and deep dives. Note what you missed, not what you got right.
- Run the scenario. Load the matching playground scenario, predict what will break, run it, and check your prediction (next section).
- Answer the follow-ups before opening them; they are the questions that decide between levels.
- Grade yourself with the rubric, then repeat a week later without looking. Spaced repetition beats rereading.
- Practice in pairs with the mock interview script: one plays the interviewer, using the follow-ups as probes.
How to use the playground with a case
Each case embeds the System Design Playground preloaded with its scenario. The playground is a simulator, not a benchmark: its numbers are illustrative, but the shapes (where the queue grows, when p99 bends, which component saturates first) are the ones you will see in real systems and in the labs.
flowchart LR
p["Predict<br/>what breaks first?"] --> r["Run<br/>load / spike profile"]
r --> o["Observe<br/>utilization, p99,<br/>errors, backlog, cost"]
o --> c["Change one thing<br/>replicas, cache, queue,<br/>timeout, partition"]
c --> e["Explain<br/>with the numbers<br/>of section 2"]
e --> p - Predict before you run. Write down which component you expect to saturate and at what load. Being wrong is the useful part.
- Change one thing at a time. Add a cache or replicas or a queue, never all three, so you know which change moved the metric.
- Use the profiles:
loadfor steady state,spikefor the BoxOffice 10:00 moment,stressandbreakpointto find the knee,chaos(or the chaos level) to kill or slow components and watch failure modes. - Connect it to the estimates. If the page says the cache must absorb 95% of reads, look at the hit ratio; if Little's Law says 40 calls are in flight, look at the concurrency of the dependency.
- Export your design (JSON) when you like it: it is the format of the playground exercise.
The cases at a glance
Suggested order: from the easy warm-ups to the flagship. The difficulty is the usual level at which the problem is asked; every case has a senior version.
| Case | Difficulty | Key concepts | Palette components | Scenario |
|---|---|---|---|---|
| URL shortener | base62, ID generation vs. hashing, 301/302, cache-aside, async analytics | lb app cache nosql kafka analytics | url-shortener | |
| Rate limiter | token bucket, sliding window, Lua atomicity, 429, fail-open/closed | apigw lb waf cache metrics | rate-limiter | |
| Distributed cache | consistent hashing, virtual nodes, eviction (LRU/LFU/W-TinyLFU), replication, hot keys | cache app nosql metrics | read-heavy-cache, sharding | |
| Search autocomplete | trie + top-k, offline aggregation, immutable snapshots, prefix sharding, debouncing | cdn search cache stream dwh worker | search-autocomplete | |
| Notification system | queue per channel, retries + DLQ, dedup, preferences, provider failover, scheduled campaigns | scheduler queue worker notifications email thirdparty | notification-system | |
| News feed | fan-out on write vs. read, celebrities, timeline cache, hydration, ranking, cursors | app cache nosql kafka worker objstore cdn | news-feed | |
| Chat | WebSocket gateways, session registry, pub/sub, per-conversation sequence, receipts, presence | lb app pubsub nosql cache notifications | chat | |
| Ride sharing | write-heavy locations, geohash/quadtree/H3, matching with locks, trip state machine | mobile apigw stream cache sql payment | ride-sharing | |
| Video streaming | pre-signed uploads, transcoding DAG, ABR (HLS/DASH), CDN + shield, egress cost | cdn objstore queue worker sql analytics | video-streaming | |
| Payment system | idempotency keys, double-entry ledger, PSP webhooks, reconciliation, outbox | apigw app sql kafka scheduler payment dwh | payment-system | |
| Ticketing (BoxOffice) | waiting room, Little's Law admission, seat holds with TTL, concurrency control, checkout state machine | cdn waf apigw queue sql cache kafka payment | flash-sale | |
| AI assistant | RAG, LLM gateway, agent loop with tools (MCP), guardrails, evals, token cost | llmgw orchestrator toolreg memory safety vectordb | ai-assistant |
The component ids are the ones of the playground palette; each is described in the component catalog.
Patterns that repeat
After a few cases you will notice that the deep dives are drawn from a short list. Recognizing the pattern in a new problem is most of the work.
| Pattern | The problem it solves | Where it appears |
|---|---|---|
| Cache the hot reads (cache-aside, CDN, L1 in-process) | Read-heavy traffic with a skewed popularity | URL shortener, news feed, autocomplete, video, ticketing catalog |
| Take slow work off the critical path (queue/stream + workers) | Spikes and slow side effects (analytics, e-mail, transcoding) | URL shortener clicks, notifications, news-feed fan-out, video, payments outbox |
| Make retries safe (idempotency keys, dedupe, conditional writes) | Networks and clients retry; providers call back twice | Payments, ticketing, chat, notifications, ride requests |
| Choose the partition key (by user, conversation, city, event, code) | One node cannot hold the data or the traffic | Chat (conversation), ride sharing (city), ticketing (event), cache (key ring) |
| Protect what cannot scale (admission control, rate limits, bulkheads) | A hot row, a primary, a provider's limit | Ticketing waiting room, rate limiter, payments, AI assistant quotas |
| Precompute vs. compute on read | Latency of reads vs. cost of writes | News feed fan-out, autocomplete top-k, video renditions |
| Stateful edges, stateless core | Long-lived connections | Chat gateways, ride-sharing driver connections, live streams |
| Strong consistency only where it matters | Correctness vs. availability and cost | Seats, payments and driver assignment strong; feeds, counters, positions eventual |
BoxOffice everywhere
Every case page has a BoxOffice connection: short links in ticket SMS (URL shortener), "5 holds per minute" (rate limiter), the "Following" tab when an artist announces a tour (news feed), fan groups during a festival (chat), 60 000 fans leaving the stadium (ride sharing), trailers on event pages (video), "doors open in 2 h" (notifications), the payment adapter (payments), search-as-you-type for artists (autocomplete), the support assistant (AI) and, of course, the flash sale itself (ticketing).
Best practices
- Write, for every box of the design, the number that put it there and what it costs β "waiting room: 33,000 holds/s against ~1,100; costs a queue and a fair-ordering rule". A box without a number is the first one a reviewer removes.
- Name the one resource that cannot scale, and protect it first β the hot seat row, the payment provider's quota, the LLM provider's tokens per minute; admission control goes in front of it before any other optimization.
- Give every write that crosses the network an idempotency key β holds, payments, notifications; retries happen at every layer. In BoxOffice: the same
Idempotency-Keytravelsorder β payment β PSP(lab 9). - Choose the consistency of each piece of data, and write it down β seats and payments strong, counters and feeds eventual; the table is part of the design doc, not a hallway decision.
- Load-test the predicted peak before the event, with the slow dependency stubbed β the knee is measured, not assumed. In BoxOffice: lab 2 finds the knee and lab 11's performance gate keeps it.
Common pitfalls in design interviews
- Jumping to the solution ("we use Kafka and Cassandra") before requirements and numbers.
- Numbers that change nothing. Every estimate should end in a decision: "so the hot set fits in memory", "so we need a queue".
- Ignoring the write path or the failure path β the interviewer will ask "what happens when X is down?".
- Over-engineering: microservices, multi-region and five databases for a system with 100 requests per second. Saying "a single PostgreSQL is enough here, and this is when it stops being enough" is a senior answer.
- Monologue. Check in with the interviewer at the end of each step; they often steer you toward the deep dive they care about.
The case-studies concept map
The twelve cases are combinations of the same patterns. The map groups the cases by the pattern they share (blue), the classes that teach it, and the palette components that implement it (green); the matrix below says which classes each case tests β β a deep dive is built on it, β it is part of the design, β not central. Each case page ends with its own How it connects diagram.
flowchart LR
g1["URL shortener Β· news feed<br/>autocomplete Β· video"] --> p1["cache the hot reads<br/>(Caching, Edge)"]:::tech
g2["notifications Β· video<br/>news feed Β· payments"] --> p2["slow work off the critical path<br/>(Messaging, Compute)"]:::tech
g3["payments Β· ticketing<br/>chat Β· ride sharing"] --> p3["safe retries, strong consistency<br/>where it matters (Distributed, Databases)"]:::tech
g4["chat Β· ride sharing<br/>ticketing Β· distributed cache"] --> p4["choose the partition key<br/>(Databases)"]:::tech
g5["ticketing Β· rate limiter<br/>AI assistant"] --> p5["protect what cannot scale<br/>(Edge, Reliability)"]:::tech
p1 --> k1["cache Β· cdn"]:::comp
p2 --> k2["queue Β· kafka Β· worker"]:::comp
p3 --> k3["sql Β· payment"]:::comp
p4 --> k4["nosql Β· stream Β· cache"]:::comp
p5 --> k5["waf Β· apigw Β· queue Β· llmgw"]:::comp
classDef comp fill:#1e9e5a22,stroke:#1e9e5a
classDef tech fill:#2f6fed22,stroke:#2f6fed | Case | Distributed | Edge | Compute | Databases | Caching | Messaging | Reliability | Also tests |
|---|---|---|---|---|---|---|---|---|
| URL shortener | β | β | β | β | β | β | β | Estimation (storage over 5 years) |
| Rate limiter | β | β | β | β | β | β | β | Performance (load test of the limiter) |
| Distributed cache | β | β | β | β | β | β | β | Estimation (memory and ops/s) |
| Search autocomplete | β | β | β | β | β | β | β | Estimation (keystroke traffic) |
| Notification system | β | β | β | β | β | β | β | β |
| News feed | β | β | β | β | β | β | β | β |
| Chat | β | β | β | β | β | β | β | β |
| Ride sharing | β | β | β | β | β | β | β | β |
| Video streaming | β | β | β | β | β | β | β | Cloud-native (FinOps: egress cost) |
| Payment system | β | β | β | β | β | β | β | Network & Security (PCI DSS scope) |
| Ticketing (BoxOffice) | β | β | β | β | β | β | β | Performance (Little's Law admission, spike test) |
| AI assistant | β | β | β | β | β | β | β | AI systems β (gateway, agents, RAG, safety) |
What breaks next
Nothing in the course breaks next β the next system is yours. Sixteen chapters turned one service and one database into a design where every box has a number that put it there and a price: the waiting room because 33,000 holds/s meet ~1,100, the cache because the event pages are read 100Γ more than they change, the circuit breaker because the provider answers in 4 s instead of 200 ms. Three places test whether that reasoning became yours. The team project builds and load-tests a system through its milestones and breaks it on purpose on the game day. The mock interviews ask for it out loud, in 45 minutes, for a system you have not seen. The design doc asks you to write it down so that someone else can disagree with a number. In all three, the question is the one every chapter asked: which number puts this box here, and what does it cost?
Related
Class 1 β interview framework Β· Class 2 β estimation Β· Interview preparation and its practice problems Β· Design doc exercise Β· Team project Β· Playground.
References
The case pages cite their own sources; the books below cover most of them123.
-
XU, A. System Design Interview β An Insider's Guide, vol. 1. Byte Code LLC, 2020; XU, A.; LAM, S., vol. 2, 2022.Β β©
-
KLEPPMANN, M.; RICCOMINI, C. Designing Data-Intensive Applications, 2nd ed. O'Reilly.Β β©
-
BEYER, B. et al. Site Reliability Engineering. O'Reilly, 2016.Β β©