The 5-Step System Design Interview Framework
A system design interview is 45 minutes of structured ambiguity. The interviewer gives you a vague prompt — "Design a URL shortener," "Design a chat application," "Design a notification system" — and watches how you navigate from nothing to a concrete architecture. The prompt is deliberately underspecified. Figuring out what to build is part of the test.
Candidates who fail usually don't fail because they lack knowledge. They fail because they don't have a structure. They jump to drawing database schemas before understanding the scale. They design the entire system before asking what the system actually needs to do. They spend 30 minutes on a component that the interviewer doesn't care about.
The framework below is a repeatable process. It won't replace understanding, but it prevents the most common structural mistakes and ensures you spend your time where the interviewer is actually evaluating you.
Clarify Requirements and Scope
The first thing the interviewer evaluates is whether you can take a vague problem and turn it into a bounded one. "Design Twitter" is not a specification. Your job is to ask questions that narrow it to something you can actually design in 40 minutes.
Functional requirements
Identify the 2–3 core features. Not everything Twitter does — just the features the interviewer wants to discuss. Ask directly:
- Can users post tweets? Can they follow other users?
- Should we design the home timeline (feed of followed users' tweets)?
- Do we need search? Notifications? Direct messages?
The interviewer will tell you what to focus on. Usually it's 2–3 features. Write them down. Everything you design after this point should serve these features. If the interviewer says "focus on the timeline," don't spend 15 minutes designing the DM system.
Non-functional requirements
These constrain your architecture. Ask about:
- Scale — How many users? How many daily active users?
- Latency — Does the feed need to load in under 200ms?
- Availability — Is 99.99% uptime required?
- Consistency — Is it acceptable for a tweet to appear in feeds after a small delay (eventual consistency), or must it be visible immediately (strong consistency)?
Back-of-Envelope Estimation
The purpose of estimation is not mathematical precision. It's to figure out the order of magnitude of the problem so you can make informed architectural choices. The question you're answering: does this system need one server or a thousand?
Keep a few reference numbers in your head:
- 1 day ≈ 100,000 seconds (actually 86,400 — round up)
- 1 million × 1 KB = 1 GB
- 1 billion × 1 KB = 1 TB
Worked example: URL shortener
Suppose the interviewer says: 100 million new URLs per month, 100:1 read-to-write ratio.
Write QPS: 100,000,000 URLs / (30 days × 100,000 sec/day) ≈ 33 writes/sec Read QPS: 33 × 100 = 3,300 reads/sec Storage (per year): Each record: short URL (7 bytes) + original URL (~200 bytes) + metadata (~100 bytes) ≈ 300 bytes 100M × 12 months × 300 bytes ≈ 360 GB / year 5-year total: ~1.8 TB Conclusion: 33 writes/sec is trivially handled by a single database. 3,300 reads/sec is easily served with a cache in front. 1.8 TB over 5 years fits on a single machine's disk. This is NOT a sharding problem. Don't design one.
That last line is the point. The estimation told you something concrete: this system does not require a distributed database. If you immediately jumped to sharding, you'd be over-engineering and the interviewer would notice.
API Design and Data Model
Before you draw architecture boxes, define what goes in and out. This forces you to think concretely about the system's interface before deciding how to build it internally.
API endpoints
Write the 2–3 core API calls. Keep them minimal:
POST /api/v1/urls
Body: { "original_url": "https://example.com/very-long-path" }
Response: { "short_url": "https://sys.iq/abc1234", "expires_at": "2027-01-01T00:00:00Z" }
GET /{short_code}
Response: HTTP 301 Redirect → original_url
GET /api/v1/urls/{short_code}/stats
Response: { "clicks": 48201, "created_at": "2026-07-01T12:00:00Z" }Data model
Sketch the primary table or document structure. For the URL shortener:
Table: urls ┌────────────┬──────────────────────────────────────┬────────────┬─────────────┐ │ short_code │ original_url │ created_at │ expires_at │ │ (PK) │ │ │ │ ├────────────┼──────────────────────────────────────┼────────────┼─────────────┤ │ abc1234 │ https://example.com/very-long-path │ 2026-07-01 │ 2027-01-01 │ └────────────┴──────────────────────────────────────┴────────────┴─────────────┘ If analytics are needed: Table: click_events (short_code, timestamp, ip_address, user_agent, country)
The data model influences your architecture. If the click analytics table needs to handle 3,300 writes per second with time-range queries, that's a different storage choice than the URL lookup table. Making this explicit now prevents confusion later.
High-Level Architecture
Now draw the system. Start simple and add components only when you have a reason for them.
A useful approach: start with the minimum path. A client talks to a server, which talks to a database. Then walk through the request flow and identify where this breaks under the constraints you established in Steps 1 and 2.
Start here:
Client ──► [API Server] ──► [Database]
Then ask: what breaks under our constraints?
- 3,300 reads/sec for redirects → add a cache
- Single server is a single point of failure → add a load balancer
- Short code generation needs to be unique → add ID generation service or use hashing
Evolved architecture:
Client ──► [Load Balancer] ──► [API Server] ──► [Redis Cache]
│ │ │ (cache miss)
│ │ ▼
│ └──────────► [PostgreSQL]
│
└──► [API Server] (stateless, horizontally scaled)Each component should be there for a stated reason. The interviewer does not want to see a diagram with every possible distributed systems component. They want to see that each box solves a specific problem from your requirements.
Walk through the request flow
After drawing the diagram, trace a request through it. For the URL shortener:
- User sends
GET /abc1234to the load balancer. - Load balancer routes to an API server.
- API server checks Redis for
abc1234. Cache hit → return 301 redirect immediately. - Cache miss → query PostgreSQL for the original URL. Store result in Redis with a TTL. Return 301 redirect.
This walkthrough exposes gaps. What happens if PostgreSQL is down? What if the short code doesn't exist? What's the cache TTL? These are the kinds of details that lead naturally into Step 5.
Deep Dive and Bottleneck Resolution
This is where the interview is won or lost. Steps 1–4 establish competence. Step 5 demonstrates engineering depth. The interviewer will either ask you to go deep on a specific component, or expect you to proactively identify the interesting problems in your design.
Identify the hard problems
For each system, there are usually 2–3 genuinely interesting engineering problems. For a URL shortener, these might be:
- Short code generation. How do you generate 7-character codes that are unique across all servers? Options: hash the URL and take the first 7 characters (collision risk), use a counter with base62 encoding (requires coordination), pre-generate ranges and assign them to servers (partition the key space).
- Cache invalidation for analytics. If you cache redirect URLs aggressively, you still need to count clicks. Do you log every redirect synchronously (adds latency) or asynchronously via a message queue (eventual consistency on click counts)?
- Handling expired URLs. Do you lazily check expiration on read, or run a background cleanup job? If lazy, expired entries stay in cache until they're accessed. If active, you need a way to scan and purge efficiently.
Pick one of these and go deep. Show the tradeoffs. For short code generation, you might say:
This kind of reasoning — comparing options, identifying failure modes, making a decision based on the specific constraints — is exactly what the interviewer wants to see.
Common Mistakes That Fail Candidates
- Drawing before thinking. Starting with a diagram before establishing requirements and scale means every component choice is ungrounded. The interviewer will ask "why did you add a cache?" and you won't have a quantitative answer.
- Designing everything. If the prompt is "Design Twitter," and you spend equal time on the tweet service, the DM service, the notification service, the search service, and the ads service, you've gone shallow on all of them. Go deep on the core feature the interviewer cares about.
- Not driving the conversation. The interviewer expects you to lead. If you sit quietly waiting for the next question after each step, you're forcing the interviewer to do the work of structuring the discussion. Move between steps yourself. Say "I've covered the high-level architecture — the most interesting problem here is the feed ranking. Should I go deeper on that?"
- Ignoring tradeoffs. Every design decision has a cost. If you say "we'll add a cache" without mentioning cache invalidation, or "we'll shard the database" without mentioning cross-shard queries, the interviewer sees a candidate who knows vocabulary but not engineering.
- Premature optimization. Proposing Kafka, microservices, and sharding for a system that handles 33 writes/sec signals that you don't understand when complexity is justified. Always let the numbers drive the architecture, not the technology list you've memorized.