Chapter 78: The 45-Minute Interview Framework

System design interviews are not coding interviews. You're not judged on perfect answers—you're judged on how you think, communicate, and handle ambiguity. This chapter gives you a battle-tested framework to structure your 45 minutes so you hit all the signals interviewers are looking for.

Time Allocation: The 5-5-15-15-5 Rule

Most candidates spend 30 minutes drawing boxes and rush the deep dive. Don't be that person. Use this timing.

gantt
    title 45-Minute Interview Timeline
    dateFormat mm:ss
    axisFormat %M:%S

    section Phase 1
    Requirements          :a1, 00:00, 5m

    section Phase 2
    Estimation           :a2, 05:00, 5m

    section Phase 3
    High-Level Design    :a3, 10:00, 15m

    section Phase 4
    Deep Dive            :a4, 25:00, 15m

    section Phase 5
    Wrap-up              :a5, 40:00, 5m
            
Phase Time Goal Deliverable
Requirements 5 min Clarify scope, align on what you're building List of functional + non-functional requirements
Estimation 5 min Justify scale, show you can do math QPS, storage, bandwidth numbers
High-Level Design 15 min Draw the system, explain data flow Box-and-arrow diagram with named components
Deep Dive 15 min Go deep on 1-2 areas interviewer picks Trade-offs, algorithms, failure modes
Wrap-up 5 min Address bottlenecks, ask clarifying questions Summary of trade-offs, open questions
Pro Tip: Set a mental timer. If you're 20 minutes in and still asking requirements questions, you've failed. The framework is your safety net—stick to it even under pressure.

Phase 1: Requirements (5 minutes)

This is not a formality. The interviewer is testing if you ask the right questions before jumping to solutions.

What to Clarify

  1. Functional Requirements: What must the system do?
  2. Non-Functional Requirements: Scale, latency, consistency
  3. Out of Scope: What you're NOT building (saves time)
Template: 5 Key Questions
1. Who are the users? (consumers, businesses, internal)
2. What are the core features? (read-heavy, write-heavy, real-time?)
3. How many users? (DAU, scale expectations)
4. What are the SLAs? (availability, latency p99)
5. What can we defer? (analytics, mobile apps, internationalization)

Example: Design Twitter

Good Questions: Bad Questions:

Output: Requirements Doc

Write on the board or doc. The interviewer should see this clearly.

Twitter Requirements Example
FUNCTIONAL:
- Users can post tweets (280 chars)
- Users can follow others
- Home timeline shows tweets from followees
- Search tweets by keyword

NON-FUNCTIONAL:
- 100M DAU
- Read-heavy (100:1 read:write)
- Timeline latency < 500ms (p99)
- High availability (99.9%)

OUT OF SCOPE:
- Media uploads (images/video)
- Direct messages
- Ads, analytics
Red Flag: If you skip requirements and start drawing, the interviewer thinks you don't handle ambiguity well. Always spend 5 minutes here, even if it feels slow.

Phase 2: Estimation (5 minutes)

This phase proves you understand scale. Even if your math is slightly off, showing the process is what matters.

The Formula Chain

graph LR
    DAU[Daily Active Users] -->|× actions/day| Total[Total Daily Requests]
    Total -->|÷ 86400 × peak| QPS[QPS]
    QPS -->|× response size| BW[Bandwidth]
    Total -->|× data size × retention| Storage[Storage]
            

Step-by-Step: Twitter Estimation

Capacity Math (Show Your Work!)
GIVEN:
- 100M DAU
- Each user posts 2 tweets/day, reads 100 tweets/day

WRITE QPS:
- Total writes = 100M × 2 = 200M tweets/day
- Writes/sec = 200M / 86400 ≈ 2,300 writes/sec
- Peak (3x avg) = 7,000 writes/sec

READ QPS:
- Total reads = 100M × 100 = 10B reads/day
- Reads/sec = 10B / 86400 ≈ 115,000 reads/sec
- Peak = 345,000 reads/sec

STORAGE (5 years):
- Tweet size = 280 chars + metadata ≈ 500 bytes
- Daily new data = 200M × 500 bytes = 100 GB/day
- 5 years = 100 GB × 365 × 5 ≈ 180 TB

BANDWIDTH:
- Write: 7K writes/sec × 500 bytes = 3.5 MB/sec
- Read: 345K reads/sec × 500 bytes = 172 MB/sec
Quick Reference:
- 1M requests/day ≈ 12 requests/sec
- 100M DAU with 10 actions = 1B requests/day ≈ 12K QPS
- Peak = 2-3x average (use 3x to be safe)
- 1 GB = 1 billion bytes (10^9, not 2^30 for estimation)
What Interviewers Look For: Showing your work. Even if you forget the exact number of seconds in a day (86,400), write "≈ 100K" and move on. Approximations are fine. Saying "I don't know" without trying is not.

Phase 3: High-Level Design (15 minutes)

This is the meat. Draw boxes, name components, explain data flow. Go breadth-first, not depth-first.

The HLD Blueprint

  1. Start with clients: Web, mobile, API
  2. Add load balancer: Distribute traffic
  3. Add API servers: Stateless application tier
  4. Add databases: SQL, NoSQL, cache
  5. Add async components: Message queues, workers
  6. Add storage: Object storage, CDN
graph TB
    Client[Client
Web/Mobile] DNS[DNS] CDN[CDN] LB[Load Balancer] subgraph API Layer API1[API Server 1] API2[API Server 2] API3[API Server 3] end Cache[Redis Cache] subgraph Data Layer DB1[Primary DB
PostgreSQL] DB2[Replica DB] DB3[NoSQL
Cassandra] end MQ[Message Queue
Kafka] Worker[Background Workers] S3[Object Storage
S3] Client --> DNS DNS --> CDN CDN --> LB LB --> API1 LB --> API2 LB --> API3 API1 --> Cache API2 --> Cache API3 --> Cache API1 --> DB1 API2 --> DB1 API3 --> DB1 DB1 --> DB2 API1 --> DB3 API1 --> MQ MQ --> Worker Worker --> S3

How to Present It

Don't just draw. Narrate the flow.

Example Narration (Twitter):

"When a user posts a tweet, the request hits the load balancer, which routes to an API server. The API server writes to PostgreSQL (primary) and publishes an event to Kafka. A background worker reads from Kafka and fans out the tweet to followers' timelines in Redis (pre-computed timelines for fast reads)."

"For reading, the home timeline query hits Redis cache first (O(1) lookup). If cache miss, we fall back to Cassandra (wide-column store, good for timeline data). We serve 99% of reads from cache."

Component Justification

Every box you draw, be ready to justify.

Component Why Not Alternative?
Load Balancer Need to distribute traffic across API servers, handle failover
Redis Cache Sub-millisecond reads, 345K QPS is too high for DB
Kafka Decouple write path from fanout, replay if worker fails
Cassandra Wide-column store optimized for timeline queries (user_id + timestamp), scales horizontally
PostgreSQL ACID for tweets, user data (small writes, simple schema)
Common Mistake: Drawing 20 components but not explaining any. Breadth without depth is a signal of shallow understanding. Draw 5-7 components, explain each one well.

Data Flow: Write vs Read

Always separate write and read paths. They have different constraints.

Twitter Write Path
1. User posts tweet via API
2. API server validates, writes to PostgreSQL (user, tweet table)
3. API server publishes event to Kafka (tweet_id, user_id, timestamp)
4. Return 201 Created to user (async fanout happens in background)
5. Worker consumes Kafka event
6. Worker fetches followers from Cassandra (user_id → follower_ids)
7. Worker writes to Redis (fanout: for each follower, add tweet_id to their timeline sorted set)
Twitter Read Path
1. User requests home timeline via API
2. API server checks Redis: ZREVRANGE user:{user_id}:timeline 0 100
3. If cache hit: return tweet IDs, fetch tweet content from PostgreSQL (or cache)
4. If cache miss: query Cassandra (wide-column: SELECT * FROM timelines WHERE user_id = ? ORDER BY timestamp DESC LIMIT 100)
5. Populate Redis cache for next request (TTL = 1 hour)

Phase 4: Deep Dive (15 minutes)

The interviewer will pick 1-2 areas to dive deeper. This is where seniority shows.

Common Deep Dive Topics

Example: Hot User Problem

Problem: A celebrity with 100M followers posts a tweet. Fanout would write 100M timeline entries to Redis—this takes minutes and crushes the system.

Solution 1: Hybrid Fanout

Solution 2: Sampled Fanout

Trade-offs:

Senior Signal: Presenting multiple solutions with trade-offs. Juniors give one answer. Seniors say "There are three approaches, here's why I'd pick this one for this use case."

Database Deep Dive: Schema Design

PostgreSQL Schema
CREATE TABLE users (
    user_id BIGINT PRIMARY KEY,
    username VARCHAR(50) UNIQUE NOT NULL,
    created_at TIMESTAMP
);

CREATE TABLE tweets (
    tweet_id BIGINT PRIMARY KEY,
    user_id BIGINT REFERENCES users(user_id),
    content TEXT,
    created_at TIMESTAMP,
    INDEX idx_user_created (user_id, created_at DESC)
);

CREATE TABLE follows (
    follower_id BIGINT REFERENCES users(user_id),
    followee_id BIGINT REFERENCES users(user_id),
    created_at TIMESTAMP,
    PRIMARY KEY (follower_id, followee_id),
    INDEX idx_followee (followee_id)
);
Cassandra Schema (Wide-Column)
CREATE TABLE timelines (
    user_id BIGINT,
    tweet_id BIGINT,
    timestamp TIMESTAMP,
    PRIMARY KEY (user_id, timestamp)
) WITH CLUSTERING ORDER BY (timestamp DESC);

-- Query: SELECT * FROM timelines WHERE user_id = 12345 LIMIT 100;
-- Fast because data is co-located by partition key (user_id)

Phase 5: Wrap-up (5 minutes)

Don't skip this. Summarize, acknowledge bottlenecks, ask intelligent questions.

What to Cover

  1. Bottlenecks: "The fanout worker is a bottleneck. If a celebrity posts, we'd queue 100M writes. We'd need to shard workers or use hybrid fanout."
  2. Next Steps: "If we productionize this, I'd add monitoring (fanout lag, cache hit rate), rate limiting, and chaos testing."
  3. Trade-offs: "We optimized for read latency at the cost of write complexity. If write latency mattered more, we'd simplify fanout."
Strong Close: "I know we didn't cover X (e.g., disaster recovery, multi-region). If we had more time, I'd discuss how we replicate data across regions and handle failover. Are there areas you'd like me to elaborate on?"

Common Mistakes (and How to Avoid Them)

Mistake Why It's Bad Fix
Jumping to solution Shows you don't handle ambiguity Spend 5 min on requirements, even if obvious
Over-engineering You're solving for 1B users when scale is 1M Match complexity to requirements
Ignoring scale Single DB when you need 100K QPS Do the math in Phase 2, justify every component
No trade-offs Suggests you don't understand constraints For every decision, say "Alternative is X, but I chose Y because..."
Silent design Interviewer can't read your mind Think out loud, narrate your thought process
Not asking questions Looks like you're not collaborative Engage interviewer: "Does this make sense?" "What would you prioritize?"

Signal Levels: What Each Level Demonstrates

Level Expectations What Sets Them Apart
Junior (L3-L4) Can follow the framework, draw a basic system, explain data flow Needs prompting on trade-offs, struggles with scale
Mid (L5) Follows framework confidently, justifies components, handles 1-2 deep dives Understands trade-offs but may not volunteer failure modes
Senior (L6) Proactively discusses trade-offs, multiple solutions, failure scenarios Brings up monitoring, cost, operational complexity without prompting
Staff (L7+) Designs for unknowns, considers org impact, discusses migration paths "This works today, but in 2 years when we're 10x scale, we'd need to..."
Staff-Level Signal: Discussing operational concerns. "This fanout design is elegant, but it adds operational burden—now we have Kafka to maintain, workers to scale, and lag to monitor. If our team is small, we might start with a simpler solution and migrate later." Shows you think beyond code.

Practice Template

Use this checklist for every mock interview.

Interview Checklist
☐ Requirements (5 min)
  ☐ Asked 5+ clarifying questions
  ☐ Wrote down functional requirements
  ☐ Wrote down non-functional (scale, SLA)
  ☐ Defined out-of-scope

☐ Estimation (5 min)
  ☐ Calculated QPS (read + write)
  ☐ Calculated storage (5-10 years)
  ☐ Calculated bandwidth
  ☐ Showed work (not just final numbers)

☐ High-Level Design (15 min)
  ☐ Drew clients, LB, API, DB, cache, queue
  ☐ Named components (not just "database")
  ☐ Explained write path
  ☐ Explained read path
  ☐ Justified each component

☐ Deep Dive (15 min)
  ☐ Waited for interviewer to pick topic
  ☐ Showed schema or algorithm
  ☐ Discussed trade-offs
  ☐ Handled failure mode

☐ Wrap-up (5 min)
  ☐ Acknowledged bottlenecks
  ☐ Suggested next steps
  ☐ Asked if interviewer wants to dig deeper

Complete 45-Minute Example: Design a Chat System

Here's a full walkthrough of a strong interview performance, minute-by-minute. This is what a senior engineer's answer looks like.

[0:00-5:00] Requirements Phase

Candidate: "Let me start by clarifying the scope. Are we designing 1:1 chat, group chat, or both?"

Interviewer: "Both. 1:1 and group chat up to 500 users per group."


Candidate: "Got it. What scale are we targeting—10 million or 1 billion users?"

Interviewer: "Let's say 500 million daily active users."


Candidate: "Perfect. A few more questions: Do we need end-to-end encryption like WhatsApp? Should we support media sharing—images, videos, files? Do we need read receipts and typing indicators?"

Interviewer: "Yes to read receipts and typing indicators. Media sharing is optional for now—let's keep it simple with text. E2E encryption is a nice-to-have but not required for this interview."


Candidate: "Understood. Last question: What's our availability and latency target?"

Interviewer: "High availability—99.95%. Message latency should be under 200ms p99."


Candidate writes on the board:

FUNCTIONAL REQUIREMENTS:
- 1:1 chat and group chat (up to 500 users)
- Send/receive text messages
- Read receipts (who has read)
- Typing indicators (who is typing)
- Message history (persistent storage)

NON-FUNCTIONAL:
- 500M DAU
- 99.95% availability
- <200ms message latency (p99)
- Real-time delivery (WebSocket)

OUT OF SCOPE:
- Media uploads (images/video)
- E2E encryption
- Voice/video calls

[5:00-10:00] Estimation Phase

Candidate: "Let me estimate the scale. I'll assume each user sends 40 messages per day and receives 40 messages."

WRITE QPS:
- 500M DAU × 40 msgs/day = 20B messages/day
- 20B / 86,400 sec ≈ 230,000 writes/sec
- Peak (3x): ~700K writes/sec

READ QPS (receiving messages):
- Same as writes: 230K reads/sec
- But also: load message history, sync across devices
- Estimate 2:1 read:write ratio = 460K reads/sec

STORAGE (5 years):
- Avg message size: 100 bytes (text + metadata)
- Daily: 20B msgs × 100 bytes = 2 TB/day
- 5 years: 2 TB × 365 × 5 = 3,650 TB ≈ 3.7 PB

CONCURRENT CONNECTIONS:
- If 10% of DAU are online simultaneously: 50M concurrent connections
- WebSocket connections require persistent TCP, so we need many servers

Candidate: "Does this scale match your expectations?"

Interviewer: "Yes, looks reasonable. Continue."

[10:00-25:00] High-Level Design Phase

Candidate: "I'll draw the architecture now. Let me start with the core components."

[Candidate draws on whiteboard]

graph TB
    Client1[Client
Web/Mobile] Client2[Client
Web/Mobile] LB[Load Balancer] subgraph "WebSocket Gateway Cluster" WS1[WS Gateway 1] WS2[WS Gateway 2] WS3[WS Gateway 3] end subgraph "Backend Services" ChatSvc[Chat Service] PresenceSvc[Presence Service] GroupSvc[Group Service] NotifSvc[Notification Service] end subgraph "Data Layer" Cache[Redis
Online Users] MsgDB[Cassandra
Message Store] MetaDB[PostgreSQL
User/Group Metadata] end MQ[Kafka
Message Queue] S3[S3
Media Storage] Client1 --> LB Client2 --> LB LB --> WS1 LB --> WS2 LB --> WS3 WS1 --> MQ WS2 --> MQ WS3 --> MQ MQ --> ChatSvc ChatSvc --> MsgDB ChatSvc --> Cache ChatSvc --> GroupSvc GroupSvc --> MetaDB WS1 -.->|Push| Client1 WS2 -.->|Push| Client2

Candidate explains:

"Here's the data flow for sending a message:

  1. User A sends message via WebSocket to Gateway 1
  2. Gateway publishes to Kafka (topic: 'chat.messages'). This decouples send from delivery—if User B is offline, message is durable.
  3. Chat Service consumes from Kafka, writes message to Cassandra (message store), and determines recipients (1:1 = User B; group = fetch group members from PostgreSQL)
  4. Chat Service looks up User B's connection in Redis: 'user:123:connection' → 'ws_gateway_2'
  5. Chat Service pushes to Gateway 2 (where User B is connected), which delivers message over WebSocket
  6. User B sends read receipt back through Gateway, which updates Redis ('msg:456:read_by' → [user_b])

"Component justifications:

[25:00-40:00] Deep Dive Phase

Interviewer: "This looks good. Let's dive deeper. How do you handle message ordering in group chats? If 5 users send messages simultaneously, how do you ensure everyone sees them in the same order?"


Candidate: "Great question. This is a distributed systems ordering problem. Here are three approaches:"

Option 1: Centralized Sequencer

Option 2: Lamport Timestamps

Option 3: Hybrid (My Recommendation)

Candidate: "I'd go with the hybrid approach. For most group chats, traffic is low enough that a centralized sequencer works fine. For extremely high-traffic groups—like a company-wide announcement channel—we accept eventual consistency because users understand it's chaotic anyway."


Interviewer: "Makes sense. One more thing: What if a user is connected on multiple devices—web and mobile simultaneously? How do you handle read receipts?"


Candidate: "Good catch. We need to track per-device connections. In Redis:"

user:123:devices:
  - device_1 (web): ws_gateway_1
  - device_2 (mobile): ws_gateway_3

When User 123 sends a message:
  - Deliver to ALL devices except the sender's device
  - Use device_id in the WebSocket handshake to identify sender

Read receipts:
  - Mark message as "read" when ANY device reads it
  - Update: msg:456:read_by → {user_123: timestamp}
  - Sync read state across all devices via push notification

[40:00-45:00] Wrap-up Phase

Candidate: "Let me summarize the key trade-offs we made today:"


Candidate: "If we had more time, I'd want to discuss multi-region replication for global users, disaster recovery (how we handle a full datacenter failure), and rate limiting (preventing spam). Are there areas you'd like me to elaborate on?"


Interviewer: "No, this was a strong answer. You covered the key areas well. We're good here."

Why This Answer Works:

Summary

Final Advice: The framework is training wheels. Once you've done 20 mocks, you'll internalize it. But until then, stick to the structure. It's the difference between a chaotic interview and a confident one. The chat system example above is your template—memorize the flow, adapt the content to any problem.