The delivery framework is the order in which you spend a design round’s minutes: pin down the requirements as numbers, name the core entities, fix the API, estimate only what changes a decision, draw a high-level design that meets every requirement end to end, then go deep on the two or three hardest parts and close with what’s left. It isn’t a script to recite. It’s how you make sure every signal the interviewer scores has evidence behind it, and that you never run out of time halfway through a box.
Picture it first: a fifteen-minute consultation
A good family doctor has about fifteen minutes per patient and a full waiting room. Watch one at work and you see the same order every time.
They ask before they examine: where does it hurt, since when, what makes it worse. They take a few measurements, such as temperature and blood pressure, because those numbers rule things in or out. They examine the whole patient briefly so nothing obvious is missed. Then they spend most of the slot on the one symptom that could be serious, order the right test for it, and finish with what to watch for and when to come back.
A weaker doctor orders a scan before asking a single question, or spends the whole slot on a sore knee and misses the chest pain.
Map it back:
- The history is the requirements step: questions before boxes.
- The vital signs are your estimates: a few numbers, taken because they change the decision.
- The quick full examination is the high-level design: every requirement covered, shallowly.
- The focused test is a deep dive, chosen because that’s where the risk is.
- “Come back if…” is the wrap-up: the bottlenecks and failures you’d watch.
- The fifteen-minute slot is the round. The order of the steps is what lets a fixed time cover the whole patient.
The framework at a glance
Seven steps, in this order. You will sometimes merge or skip one, but you should always know which step you’re in and how many minutes it has left. The round’s format, scoring and level expectations live in how a system design interview works; this page is the method.
| Step | Goal | Artefact on the board | 45 min | 60 min | Common failure |
|---|---|---|---|---|---|
| 1. Requirements | Agree what to build and how well | 3–5 “users can…” lines, numeric targets, out-of-scope list | 5 | 7 | A feature wish-list with no numbers |
| 2. Core entities | Name the nouns | 4–6 entities, key fields, relationships | 2 | 2 | A full schema with every column |
| 3. API | Fix the contract | 3–5 endpoints with request and response | 3 | 4 | CRUD for every table; no idempotency or pagination |
| 4. Estimates | Numbers that pick a design | 1–3 lines of arithmetic, each with its decision | 0–2 | 0–3 | Ten minutes of maths that changes nothing |
| 5. High-level design | A design that works end to end | Boxes and arrows, one traced flow per requirement | 9 | 10 | Boxes nobody traced; buzzword stacking |
| 6. Deep dives | Depth where it’s hard | Options, numbers and a decision for each dive | 14 | 20 | Options listed, nothing chosen |
| 7. Wrap-up | Show you know what’s left | Bottleneck, failure mode, next step | 3 | 4 | Running out of time mid-sentence |
The sequence is not arbitrary. Google’s SRE Workbook describes non-abstract large system design (NALSD) as two phases: first ask whether a design is possible and whether you can do better, then scale it up and ask whether it is feasible within real hardware and money, and whether it is resilient. Steps 1 to 5 get you a possible design; the deep dives make it feasible and resilient. The workbook also admits that in practice you “bounce around” between the questions, which is fine as long as you come back to the plan.
Keep the board organised
Agree a layout in the first minute and keep it all round. The interviewer is reading your board as notes, and you will point back at it constantly.
- Requirements and numbers go top left and stay there. Amazon’s system design prep video tells candidates to write the answers down so they can come back to them, because “a lot of times we end up getting requirements but not using them in the design”.
- Entities and the API sit underneath, a line each, not paragraphs.
- The diagram takes the big space and flows left to right: clients, edge, services, data. Leave gaps for the boxes you will add later.
- A parking lot holds anything you defer. “I’ve noted it; I’ll come back after the write path” keeps you moving without ignoring the interviewer.
Step 1: pin the requirements
Meta’s interview guide describes problem navigation as asking questions “to reduce ambiguity, identify the most critical problems, understand what is needed for quantitative analysis, and define a requirement set to design to”. That last phrase is the goal of this step: a short written set that you will design against and check against.
Functional: three to five “users can…” statements
Write capabilities a user would notice, not components: “customers can watch the rider move on a map”, not “a location service”. Three to five is enough to fill a round. If the prompt implies ten, ask which three matter most and park the rest. Each statement becomes a flow you trace in step 5, so start each with a verb.
Non-functional: numbers, not adjectives
“Scalable, fast and highly available” describes every system and constrains none. Turn each quality into something you could test:
| Quality | Question to ask | Write it as |
|---|---|---|
| Scale | How many users, how often, what peak? | 2M orders a day; the dinner hour carries 15% of them |
| Latency | Which operation, which percentile? | New status on screen within 2 s at p95 |
| Availability | Which path, over what window? | Tracking reads 99.9% a month (about 43 minutes of downtime) |
| Consistency | Per operation: may it be stale? | Status never goes backwards; the rider’s pin may be seconds old |
| Durability | What must survive a crash? | Status history kept for disputes; the live pin can be lost |
| Cost and rules | Budget, devices, regulation | Rider pings every 4 s to save battery; location shown only during delivery |
The SRE Workbook’s worked NALSD example states its targets exactly this way: “99.9% of dashboard queries complete in < 1 second” and “99.9% of the time, the CTR data displayed is less than 5 minutes old”. One latency target and one freshness target, each with a percentage and a threshold. Copy that shape. The availability arithmetic is in availability and the nines, and the reasoning for choosing consistency per operation is in CAP and PACELC.
Out of scope, said out loud
Name three or four things you won’t design: payments, sign-up, the recommendation model. It protects your minutes and invites correction early. If the interviewer cares about one of them, you hear it at minute 6, not minute 30.
Propose numbers instead of asking open questions
“How many users?” often gets “you tell me”. Offer an assumption instead: “I’ll assume 2 million orders a day with a dinner peak; tell me if that’s an order of magnitude off.” Amazon’s prep video also suggests stating and validating assumptions such as “there’s a payment service” that already exists, which shrinks the problem honestly.
Steps 2 to 4: entities, API and the numbers that matter
Step 2: core entities
List the nouns the system stores or moves, with their key fields and relationships, and stop there. Four to six is typical, and two minutes is plenty. Google’s resource-oriented design guide (AIP-121) proposes the same order for any API: the resources (nouns) first, then their relationships, then each resource’s schema, and only then the methods. Indexes, column types and denormalisation wait until a deep dive needs them; see data modeling and denormalization.
Step 3: the API or interface
Sketch one endpoint, RPC or event per functional requirement, with the shape of the request and response. Three details separate a careful API from a sketchy one:
- Idempotent writes. RFC 9110 calls a method idempotent when repeating it has the same intended effect as sending it once. PUT, DELETE and the safe methods such as GET qualify; POST does not, and a client should not automatically retry one unless it knows the request is safe to repeat. So give creates an idempotency key. Stripe’s API, for example, takes a client-generated key (it suggests a V4 UUID), saves the first response for that key, replays it on retries, and errors if the same key arrives with different parameters. More in idempotency.
- Paginated lists. Google’s AIP-158 says list methods must paginate from the start, because adding pagination later silently breaks clients that expected everything. Use a page size, an opaque page token and a next-page token; see offset vs cursor pagination.
- The API is not the database. AIP-121 calls an API that mirrors the schema an anti-pattern. Expose what the client needs, such as a tracking view, not your tables.
Full depth, including versioning and errors, is in API design for system design interviews.
Step 4: estimates, only where they change a decision
Before you calculate anything, say which decision it informs: one database or shards? Can the live state sit in memory? Poll or push? If no plausible answer would change the design, skip the sum and say so.
The SRE Workbook shows what a decisive estimate looks like. At 500,000 log entries a second and about 200 IOPS per hard disk, one write per entry needs (5 × 10⁵) ÷ 200 = 2,500 disks, and the single-machine design is dead in one line. The same chapter warns that “sound reasoning and assumption making are more important than any final values”.
You can estimate straight after the requirements or just in time, inside the deep dive that needs the number. Both work. The method is in back-of-envelope estimation and the constants in numbers to know.
Step 5: a high-level design, one requirement at a time
The goal is a boring design that works: every functional requirement satisfied end to end at modest scale, before you optimise anything. In NALSD terms, prove it is possible before you ask whether it is feasible.
- Take requirement 1. Draw the client, the service that handles it and where its state lives. Walk one request through out loud: which endpoint, which service, which write.
- Take requirement 2. Reuse boxes where you can and add only what is missing. Repeat for each requirement.
- Name each store’s job. What it holds, its key, and why that kind of database: “orders in Postgres, keyed by order ID, because status changes need transactions”. See databases for system design interviews.
- Check the corner. Every functional requirement has a traced path; every number has a plan, even if the plan is “deep dive”.
Amazon’s prep video demonstrates the tracing habit on an online bookstore: the search box calls the search API, which calls the books API, and the response becomes a rendered page. One user action, end to end.
Keep the first version small: stateless services, one database, and a cache or queue only where a requirement demands it. Add boxes during the deep dives, where you can justify them with numbers.
In the interview
Narrate with the requirement attached: “This covers requirement 2. The 2-second freshness target worries me with polling, so I’ll make that my first deep dive.” One sentence earns credit for the design and sets up the depth.
Steps 6 and 7: deep dives and the wrap-up
Picking the deep dives
Choose from four sources, roughly in this order:
- The requirement that is hardest at the stated scale. Usually it’s the number that made you nervous in step 4.
- The interviewer’s hints. A question about a component is usually an invitation to go deep on it.
- Single points of failure visible in your own diagram: one database, one region, one queue. See single point of failure.
- Consistency hot spots, anywhere two writers race for the same thing: a seat, a balance, a rider.
The prompt’s wording usually tells you where the first one is.
| Signal in the prompt | Likely deep dive | Read |
|---|---|---|
| “live”, “real-time”, “watch it move” | Push channel (polling, SSE, WebSockets) and fan-out | Real-time updates |
| “book”, “limited seats”, “tatkal”, “flash sale” | Holds, locking, double booking under a burst | Contention and double booking |
| “pay”, “wallet”, “transfer”, “retry” | Idempotency, exactly-once effects, the ledger | Idempotency |
| “feed”, “followers”, “celebrity” | Fan-out on write or read, hot keys | Scaling reads |
| “nearby”, “within 3 km” | Geospatial index and its update rate | Proximity search |
| “upload”, “video”, “large files” | Chunked, resumable uploads; blob storage; CDN | Large file uploads |
| “millions of writes a second”, “events”, “clicks” | Partition key, write path, sharding | Scaling writes |
| “takes minutes”, “report”, “transcode” | Async jobs, queues, progress and retries | Long-running jobs |
| “global”, “99.99%”, “any region” | Replication, failover, consistency across regions | Multi-region and active-active |
Running one
Every good deep dive has the same five beats, and you can say them in about six minutes.
- Problem. One sentence with its number: “push 12.5k pin updates a second to 100k screens within 2 seconds”.
- Options. Two or three real alternatives, including the simple one. Meta’s guide asks candidates to “avoid focusing on only optimal solutions”, because it is “much more interested in seeing how you think through basic tradeoffs”.
- Trade-offs with numbers. For each option, what you gain and what you pay, measured where you can.
- Decide. Pick one, and say what would make you change your mind.
- Monitor. The metric that would tell you in production that the choice is failing.
How many, by level
| Level | Deep dives | Who picks them |
|---|---|---|
| Mid-level | One, perhaps two | Often the interviewer |
| Senior | Two or three | You, unprompted, hardest first |
| Staff and above | Two or three, plus a cross-cutting thread on cost, evolution or operations | You, early, framed against the business goal |
Two finished deep dives beat four started ones. In a 45-minute round aim for two; in 60, three.
Step 7: the wrap-up
Spend two to four minutes on three short points: the bottleneck that bites first as load grows, with its number; the failure mode you are least comfortable with and its mitigation; and what you would do next with more time, including anything in the parking lot. Then stop and invite questions. A wrap-up you chose to give reads very differently from one the clock forced on you.
How the steps flex
The order holds for almost every prompt, but the weight of each step moves with the kind of system.
| Product prompt | Infrastructure prompt | Data-heavy prompt | |
|---|---|---|---|
| Examples | Food delivery, a feed, ticket booking | Rate limiter, key-value store, job scheduler | Metrics, click analytics, search indexing |
| Requirements start from | User journeys: “customers can…” | Guarantees: limits, ordering, durability, latency | Freshness and query shapes: “p95 query in 1 s, data at most 5 min old” |
| Entities and API | Several entities; HTTP endpoints | One or two entities; a library call or RPC such as allow(key) → bool |
Event schema and the queries you must answer |
| Estimates | Often one or two lines | Usually decisive: they pick the data structure and node count | Decisive: volume per day picks storage and pre-aggregation |
| Typical deep dives | Contention, fan-out, real-time delivery | Consistency, failure handling, hot keys | Write path, partitioning, late and duplicate events |
Two other variations come up often. The interviewer drives: some hand you the requirements, or ask “how would you store this?” at minute 4. Follow them, but keep filling in the requirements corner, because the deep dives need those numbers. The prompt is one component: for “design the matching engine”, the high-level design is two boxes and most of the round is deep dive. Say so up front.
When you’re behind or stuck
Check the clock at three points. In a 45-minute round you want requirements and the API on the board by about minute 15, a traced high-level design by about minute 25, and at least one deep dive finished by minute 35. Shift each checkpoint by about a third for a 60-minute round.
- Behind at minute 15? Drop the separate estimates step and say you’ll estimate inside the deep dive that needs a number. Don’t rush the requirements; designing the wrong thing costs more.
- Behind at minute 25? Finish the high-level design at a coarser grain (one box for “order service” rather than four) and name the parts you’re hand-waving. An unfinished end-to-end path hurts more than a shallow one.
- Stuck on a hard part? Go back to the requirements corner and read the relevant number out loud. Then shrink the problem the way NALSD does: “If it all fitted on one machine, what would I do?” Solve that, then ask what breaks first as you scale it out.
- Unsure between two options? Pick the simpler one, say what it costs, and say which measurement would make you switch. A reversible decision with a stated trigger is a strong answer.
- Realised an earlier choice is wrong? Say it, with the number that changed your mind: “At 50k requests a second, polling is wasteful; I’m switching tracking to push.” Correcting yourself is evidence of judgement, not a penalty.
Don’t ask the interviewer what to do next
“What would you like me to do?” hands problem navigation, a scored signal, back to the interviewer. Offer a choice instead: “I can go deeper on rider tracking or on order status ordering. I’d start with tracking, because of the 2-second target. Does that work?”
A worked example: live order tracking
Here is the framework run end to end on one prompt: “Design live order tracking for a food-delivery app.” The numbers are assumptions you would propose and the interviewer would correct.
Step 1, requirements (5 minutes). Two functional requirements: customers see each status change (placed, accepted, picked up, delivered), and customers watch the rider move on a map during delivery. Non-functional: 2 million orders a day, with 15% in the dinner hour; a new status or pin on screen within 2 seconds at p95; status never goes backwards on screen; a pin may be a few seconds old and may be lost. Out of scope: payments, rider dispatch, ETA prediction.
Steps 2 and 3, entities and API (5 minutes). Entities: Order (with a status and a version), OrderEvent (order, sequence number, new status), Rider, and LocationPoint (live only, never stored long-term). The API has three calls: POST /riders/:id/locations every 4 seconds; POST /orders/:id/transitions with the target status and an idempotency key, because rider phones on patchy networks retry; and GET /orders/:id/tracking, which returns the current state or opens a stream.
Step 4, estimates (2 minutes). These decide the push-versus-poll question and the size of the live state.
- Peak orders: 2M × 0.15 = 300k orders in the dinner hour. With about 30 minutes from order to door, about 300k × 0.5 = 150k orders are in flight.
- Watchers: if about two-thirds of those customers have the tracking screen open, that’s about 100k screens.
- Riders: if about half the in-flight orders are on the road, and some riders carry two, assume 50k moving riders. One pin every 4 seconds is 50,000 ÷ 4 = 12.5k pins a second.
- Live state: 50k pins × about 100 bytes = 5 MB. It fits in one machine’s memory many times over, so storage is not the problem; delivery is.
Step 5, high-level design (9 minutes). Trace each requirement, then add what’s missing.
- The rider app sends a pin every 4 seconds: 12.5k a second at the peak.
- The location service overwrites the rider’s latest pin in Redis and publishes it on the rider’s channel.
- Status changes from the rider or restaurant app go to the order service, with an idempotency key.
- The order service applies a change only if it moves the order forward, and appends an
OrderEventwith the next sequence number, in one transaction. - After the commit, it publishes the event on the order’s channel.
- The tracking gateway subscribes to the order and rider channels that its connected customers are watching.
- It pushes pins and status events to the customer, using the sequence number as the event ID.
- When a customer reconnects, it replays any status events the client missed from the database.
Step 6, deep dive 1: how do updates reach 100k screens within 2 seconds? Short polling every 2 seconds is 100,000 ÷ 2 = 50k requests a second, nearly all returning “no change”. WebSockets work but are two-way, and the customer sends nothing. Server-sent events fit: one long-lived HTTP response carrying text events, with reconnection built into the browser’s EventSource. MDN documents the details worth mentioning: a retry field sets the reconnection delay, a line starting with a colon is a comment you can send as a keep-alive, and without HTTP/2 browsers allow only six connections per domain, so serve the stream over HTTP/2. Decision: SSE, with 15-second polling as a fallback. Monitor render lag at p95, streams per server and reconnects per minute.
Step 6, deep dive 2: how does status never go backwards? Redis pub/sub delivers at most once: its documentation says a subscriber that disconnects loses those messages for good. Fine for pins, since the next arrives in 4 seconds; not fine for “delivered”. So status takes the durable path. The order service applies a transition only if it is legal (for example, WHERE status = 'PICKED_UP' when moving to DELIVERED), writes the event in the same transaction, and publishes after commit. Each SSE event carries its sequence number as its id. After a drop, the browser reconnects with the last ID it saw in a Last-Event-ID header, and the gateway replays newer events from the database. The client ignores sequence numbers it has already shown, and the idempotency key stops a rider’s retry applying “picked up” twice.
Step 7, wrap-up (3 minutes). The first bottleneck is open streams on the gateway on a big-match night; it scales out, because each server holds only its own clients’ subscriptions. The failure to watch is losing a Redis node: pins stop, clients fall back to polling, and status still arrives through replay. Next, from the parking lot: multi-region, and masking the rider’s position near their home.
Cheat sheet
| Step | You’re done when… | Say something like |
|---|---|---|
| 1. Requirements | 3–5 “users can…” lines, numeric targets, an out-of-scope list are on the board | “I’ll assume 2M orders a day; tell me if that’s off by 10×.” |
| 2. Entities | 4–6 nouns with key fields | “These are the things we store; columns can wait.” |
| 3. API | One call per requirement; idempotency keys on writes; paginated lists | “Creates take an idempotency key because mobile clients retry.” |
| 4. Estimates | Each number has named the decision it settles | “This tells me one database is enough, so no sharding yet.” |
| 5. High-level design | Every requirement traced end to end | “That covers requirement 2. The 2-second target is my first deep dive.” |
| 6. Deep dives | Problem, options, trade-offs with numbers, decision, monitoring | “I’ll take SSE, and switch if reconnects per minute climb.” |
| 7. Wrap-up | Bottleneck, failure mode, next steps | “What breaks first is…; what I’d watch is…” |
| Clock (45 min) | Minute 15: API done · 25: design traced · 35: one dive finished | “I’ll estimate inside the deep dive to save time.” |
How to say it in the interview
You rarely recite the framework. You show it in the first minute, by saying how you’ll spend the time:
“Here’s my plan. About five minutes to pin down what we’re building and the numbers that matter, then a quick list of entities and the API. I’ll sketch a simple design that covers every requirement end to end, and then spend most of our time on the two hardest parts, which I suspect are getting updates to screens fast and keeping order status correct. I’ll leave a few minutes at the end for bottlenecks and what I’d do next. If you’d like me to go deeper somewhere else, steer me at any point.”
What if the interviewer says, “Skip the requirements, just design it”? Take a 60-second version instead of skipping it: two functional requirements and one number, written in the corner. “Quickly, so I design the right thing: customers see status and the rider’s location, within 2 seconds, about 100k at once. Now the design.” You still need those numbers for the deep dives.
What if I reach minute 30 of 45 without starting a deep dive? Stop adding boxes. Name the hardest part, give it one full deep dive (problem, options, decision), and use the last minutes for a short wrap-up. One finished deep dive gives the interviewer more evidence than a complete-looking diagram with no depth.
Does the framework change for an infrastructure prompt? The steps don’t, but the weights do. Requirements become guarantees (limits, ordering, durability), the API becomes a function call or RPC, and the estimates usually decide the data structure and node count, so they get more time. See the rate limiter for a full example.
Isn’t a fixed framework robotic? Only if you recite it. The steps exist so nothing important gets skipped. Merge them when they’re small, reorder them when the interviewer leads, and keep the clock in your head. Interviewers notice whether the requirements drive the design, not whether you said “step 4”.
Where to go next
- How a system design interview works: the format, what interviewers score, and how expectations change by level.
- Back-of-envelope estimation: the method behind step 4, with worked examples.
- Numbers to know: the latencies, throughputs and sizes to plug in.
- Common mistakes that sink design rounds: what goes wrong at each step, and how to recover.
- API design for system design interviews: step 3 in depth.
- Real-time connections: long polling, SSE and WebSockets: the options from deep dive 1.
- Idempotency: why every write in the API takes a key.
- Design food delivery: the full problem the worked example comes from.
- Design a rate limiter: the framework applied to an infrastructure prompt.
References and further reading
- Introducing Non-Abstract Large System Design (Google SRE Workbook, chapter 12)sre.googleThe iterate-until-viable loop (possible, better, feasible, resilient), SLO-style requirements, the disks-per-IOPS estimate and “reasoning over final values”.
- Preparing for your Full Loop Interview at Meta (Software Engineer Full Loop Interview Guide, PDF)metacareers.comThe 45-minute design interview, problem navigation as defining “a requirement set to design to”, trade-offs over optimal answers, and the push-or-pull question.
- System Design Interview Prep, video transcript (Amazon Jobs)static.jobs.production.amazon-jobs.brightspot.cloudWriting requirements down and using them, validating assumptions such as existing services, entities then API, and tracing one user action end to end.
- Engineering interview process (Atlassian Careers)atlassian.comThe 60-minute systems design session, questions that “ladder”, and new trade-offs introduced mid-interview.
- RFC 9110: HTTP Semantics, section 9.2 (safe and idempotent methods)rfc-editor.orgWhich methods are idempotent, and why clients and proxies must not blindly retry non-idempotent requests.
- Idempotent requests (Stripe API reference)docs.stripe.comClient-generated idempotency keys, saved first responses, parameter checks and pruning after 24 hours.
- AIP-121: Resource-oriented design (Google API Improvement Proposals)google.aip.devResources and relationships before schemas and methods, and why an API that mirrors the database schema is an anti-pattern.
- AIP-158: Pagination (Google API Improvement Proposals)google.aip.devPaginate list methods from the start with page_size, opaque page_token and next_page_token, because adding it later breaks clients.
- Using server-sent events (MDN Web Docs)developer.mozilla.orgOne-way event streams, the id and retry fields, comment keep-alives, and the six-connection limit without HTTP/2.
- Redis Pub/Sub (Redis documentation)redis.ioAt-most-once delivery: a subscriber that disconnects loses messages, which shapes what may travel over pub/sub.