Read alongside
Designing Data-Intensive Applications: Ch. 1: Reliable, Scalable, and Maintainable Applications
How to describe load and performance (load parameters, percentiles) and reason about scalability.
Objectives
- Elicit functional and non-functional requirements (latency, availability, durability, consistency, scale, cost) and state assumptions explicitly.
- Define API contracts for the core operations, including idempotency, pagination and error semantics.
- Derive a data model and storage choice from access patterns and consistency needs.
- Estimate traffic, storage, bandwidth and concurrency from stated assumptions to within an order of magnitude.
- Identify the bottleneck and the riskiest component, and go deep on them with numbers and alternatives.
- Enumerate failure modes with detection and mitigation, and describe a safe rollout or migration plan.
- Explain how expectations differ for graduate, mid-level and senior candidates and adapt depth accordingly.
Why it matters
A design interview compresses weeks of design work into 45 to 60 minutes. Without a method, candidates either draw a familiar architecture or chase one detail and run out of time. With one, you show requirements thinking, quantitative judgment and failure awareness in a predictable order, and spend the remaining time where the problem is actually hard. The same method improves real design documents.
Core ideas
A reliable sequence, with rough time shares for a 45-minute round:
- Requirements (about 5 minutes). Functional: the few operations that matter, who calls them and what they return. Non-functional, with numbers: users and peak requests per second, read/write ratio, latency targets as percentiles, availability, durability, consistency per operation, retention, cost or compliance limits. Write assumptions down; reasonable ones are usually accepted.
- Contracts (about 5 minutes). Sketch the API for the core operations: inputs, outputs, errors, pagination, and idempotency keys for anything that may be retried. Contracts force clarity about what the system promises.
- Data model (about 5 minutes). Entities and the access patterns that read them. Choose storage by access pattern and consistency need (relational for transactions and flexible queries, key-value for high-volume point access, logs for event streams, object storage for blobs) and pick partition keys.
- Estimates (about 5 minutes). Numbers decide the architecture. A day has about 86,400 seconds, so 100 million requests per day is roughly 1,200 per second on average; assume a peak several times higher. Storage is item size times items per day times retention times replication. Concurrency is throughput times latency. Compare with what one machine or shard can sustain to find how many you need.
- High-level design (about 10 minutes). Components and data flow for reads and writes, sized. Stay simple until the numbers force complexity.
- Deep dives (about 10 minutes). The bottleneck or riskiest piece: a hot partition, a large fan-out, a consistency boundary, a queue that can back up. Compare two alternatives with their costs.
- Failures, operations and rollout (about 5 minutes). What happens when each dependency is slow or down, how you detect it, what degrades, and how you roll out or migrate safely.
Tradeoffs are the content. Every choice should come with its cost: latency for consistency, complexity for availability, money for headroom. "We could also do X, but it costs Y, so I would choose it only if Z" is often worth more than the choice itself.
Levels differ in ownership, not just knowledge.
- Graduate: a sound, simple design with correct use of standard components, reasonable estimates with some prompting, and awareness of failure modes when asked.
- Mid-level: drives the conversation, quantifies, justifies storage and partitioning, and raises failure handling, idempotency and observability unprompted.
- Senior: shapes ambiguous scope, finds the one or two decisions that matter and goes deep with numbers, weighs operability, cost, migration and team impact, and adapts smoothly when a constraint changes.
Common misconceptions
- "Start by drawing the architecture." Without requirements and numbers no box can be justified; a few minutes of clarification pays for itself.
- "More components show more knowledge." Unjustified caches, queues and services add failure modes; add each only when a requirement or estimate demands it.
- "Estimates must be precise." Order-of-magnitude accuracy with stated assumptions is the goal; the point is to see which resource dominates.
- "There is one correct design." Interviewers assess reasoning and tradeoffs; a well-defended simple design beats an undefended complex one.
- "Failure handling goes at the end." Failure modes often change the core design (idempotency, replication, queues); bring them into the deep dive.
How to approach it
Learn the sequence, then rehearse it on small prompts with a timer. Memorize a handful of orders of magnitude (memory versus SSD versus network round trips, rough throughput of common stores), for example from the latency table in Dean's keynote, remembering that exact values change with hardware. Read DDIA Ch. 1 on describing load and performance, and work the NALSD chapter to see estimates drive a design. Then move to the practice-routine topic for full timed designs.
Self-check before you finish
- Which non-functional requirements do you always ask about, and why those?
- How many requests per second is 1 billion per day, on average and at a 3x peak?
- How does a read-heavy versus write-heavy workload change the design?
- What makes an API idempotent, and where in your design does it matter?
- What would you cut if you had only 30 minutes?
- How do you decide which component to deep dive on?