System Design Interview Prep for Beginners | The Six-Step Framework
Navigating a system design interview can be highly intimidating due to the open-ended nature of the questions. To succeed under pressure, you need a structured, repeatable strategy that transforms vague, ambiguous prompts into concrete, production-ready architectures. This chapter introduces The Six-Step Framework, a systematic blueprint designed to guide you through requirements gathering, capacity estimation, API design, high-level architecture, deep-dive engineering, and bottleneck mitigation.
1. Overview of the Six-Step Framework
When an interviewer asks you to "Design Instagram" or "Design Twitter," they are not looking for a single correct answer. Instead, they want to evaluate your engineering thought process, your ability to handle ambiguity, and your systematic approach to scaling.
The Six-Step Framework allocates a standard 45-minute interview window into logical, bite-sized phases:
2. Step 1: Clarifying Requirements
Every system design question begins with an intentionally vague prompt. Your first task is to spend approximately 5 minutes making the problem statement concrete. Do not write code or draw diagrams yet. Instead, ask clarifying questions to establish the boundaries of your system.
Functional Requirements
Functional requirements define what the system must do. For a system like Instagram, you should narrow the scope down to a few core features:
- Photo Uploads: Users must be able to post and upload photos.
- User Follows: Users must be able to follow and unfollow other users.
- Home Feed: Users must be able to scroll through a timeline containing photos posted by the people they follow.
Non-Functional Requirements
Non-Functional requirements define how well the system performs its tasks. These constraints dictate your architectural choices:
- Low Latency Feed Generation: The home feed must load almost instantly (e.g., within 200ms) as soon as the user opens the application.
- High Availability: The system should prioritize availability over strict consistency (eventual consistency is acceptable for social media feeds).
3. Step 2: Back-of-the-Envelope Estimation
Once the requirements are set, you must estimate the scale of the system. This step helps you determine whether your system can run on a single database instance or if it requires highly distributed storage, caching layers, and load balancers.
The Instagram Case Study
Consider the following scale assumptions, which you should always state clearly and confirm with your interviewer:
- Daily Active Users (DAU): 10 million users.
- User Behavior Ratio: Users scroll and read far more than they post.
- An average user scrolls through 100 photos per week.
- An average user posts only 1 photo per week.
Analyzing the Read/Write Ratio
By comparing these two metrics, we can determine the system's fundamental nature:
This calculation reveals that our system is highly read-heavy.
Architectural Implications
Because reads outnumber writes by two orders of magnitude, our design must prioritize read optimization. We must focus heavily on caching strategies, read replicas, and pre-computed feeds to ensure that retrieving photos does not overwhelm our primary databases.
4. Step 3: Defining the API
With the requirements and scale established, spend about 5 minutes defining the API. The API acts as a formal contract between the client (e.g., mobile app, web browser) and your backend services.
For our simplified Instagram design, three core API endpoints are sufficient to support all functional requirements:
1. Upload a Photo
- Endpoint:
POST /v1/photos - Description: Uploads a new image file along with its metadata.
- Payload:
JSON
{ "userId": "string", "caption": "string", "imageBinary": "bytes" }
2. Follow a User
- Endpoint:
POST /v1/users/{userId}/follow - Description: Establishes a follow relationship between the current user and a target user.
- Payload:
JSON
{ "targetUserId": "string" }
3. Get Home Feed
- Endpoint:
GET /v1/feed - Description: Retrieves a paginated list of photos posted by users whom the caller follows.
- Query Parameters:
limit(integer): Number of photos to fetch.paginationToken(string): Token for fetching the next page of results.
Note: Defining these API calls also reveals your storage requirements. To support these endpoints, your system must store three distinct types of data:
- Photos: The actual image files and their associated metadata (creation time, owner ID).
- Follow List: A mapping of who follows whom (user relationships).
- Feed: A compiled list of relevant photos for each user.
5. Step 4: High-Level Design
Spend 10 to 15 minutes sketching the high-level architecture. At this stage, avoid diving into low-level details. Focus instead on drawing the primary components and showing how data flows through them.
Core Architectural Components
- Client: The mobile app or web browser initiating requests.
- Application Server: The orchestrator that handles incoming API requests, processes business logic, and communicates with storage layers.
- Relational Database (Metadata & Follows): A structured database (e.g., PostgreSQL) to store user profiles, follow relationships, and photo metadata.
- Object Storage (Photos): A dedicated, highly scalable storage system (e.g., Amazon S3) designed to store raw binary image files.
High-Level Data Flow
The following vertical workflows illustrate how data moves through the system during write (upload) and read (feed retrieval) operations:
Photo Upload Flow (Write Path)
Feed Retrieval Flow (Read Path)
Client (Mobile App)
|
| 1. Sends GET /v1/feed
v
Application Server
|
| 2. Queries follow list & photo metadata
v
Relational Database
|
| 3. Returns list of photo metadata & S3 URLs
v
Application Server
|
| 4. Returns feed JSON to Client
v
Client (Mobile App)
|
| 5. Directly fetches raw images using S3 URLs
v
Object Storage (e.g., S3)
6. Step 5: Deep Dives
Once the high-level design is established, spend 10 to 15 minutes diving deep into the system's most challenging technical bottlenecks. For Instagram, the hardest problem is Home Feed Generation at Scale.
The Core Challenge: The "Celebrity" Fan-Out Problem
When an average user with 50 followers posts a photo, updating the feeds of those 50 followers is computationally trivial. However, when a celebrity with 10 million followers posts a photo, how does that photo show up in 10 million feeds instantly without melting the system?
Real-Life Analogy: Mail Delivery vs. Bulletin Boards
Imagine two ways of distributing news in a village:
- The Mail Delivery Model (Push / Fan-out on Write): Every time someone writes a letter, a postman immediately runs to deliver a copy to all of their friends' physical mailboxes. If a highly popular figure writes a letter, the post office is instantly crushed under the weight of printing and delivering millions of copies simultaneously.
- The Bulletin Board Model (Pull / Fan-out on Read): Instead of delivering letters, everyone posts their updates on a personal bulletin board. When you want to see what's new, you walk around the village and read the boards of only the people you follow. This saves the post office from delivery spikes, but it means you have to do a lot of walking (heavy read latency) every time you want an update.
Technical Trade-offs in Feed Generation
To solve this, system designers choose between two primary models:
Push Model (Fan-out on Write)
|
| User posts a photo
v
| System immediately writes photo ID to all followers' pre-computed feed caches
v
| Pros: Fast reads (Feed is already built)
| Cons: Slow writes for celebrities (Millions of writes triggered at once)
Pull Model (Fan-out on Read)
|
| User requests their feed
v
| System queries databases of all followed users to compile the feed on-the-fly
v
| Pros: Simple write path (No pre-computation)
| Cons: Slow reads (Heavy database queries on every feed refresh)
Hybrid Approach
To balance these trade-offs, modern systems use a hybrid approach:
- For Standard Users: Use the Push Model. When they post a photo, push it directly into their followers' pre-computed feed caches.
- For Celebrities: Use the Pull Model. When a celebrity posts, do not push it to millions of feeds. Instead, when a follower requests their feed, pull the celebrity's recent posts on-the-fly and merge them into the follower's pre-computed feed.
7. Step 6: Bottlenecks and Scaling
In the final 5 minutes of the interview, perform a critical analysis of your architecture. Identify what will break first when traffic scales by 10x or 100x, and propose concrete engineering solutions.
Identifying and Resolving Bottlenecks
[Relational Database]
|
| Problem: High read traffic on Follows table causes database CPU to spike
v
[Add Cache Layer (e.g., Redis)]
|
| Solution: Cache follow lists in memory to reduce direct database queries
v
[Database Sharding & Read Replicas]
|
| Solution: Distribute read traffic across multiple read-only database replicas
The 30-Second Summary
At the very end of the interview, wrap up with a concise, high-impact summary of your design:
"To design Instagram, we established a read-heavy system supporting 10 million daily active users. We designed clean APIs for uploading photos, following users, and retrieving feeds. Our high-level architecture decouples metadata storage in a relational database from raw image storage in S3. To handle the scale of feed generation, we implemented a hybrid push/pull model to prevent celebrity posts from overwhelming our servers. Finally, we addressed scaling bottlenecks by introducing a Redis caching layer in front of our relational database to handle high-frequency read requests."
8. Summary and Key Takeaways
- Structure Beats Chaos: Under pressure, always rely on the Six-Step Framework to keep your thoughts organized and prevent you from jumping straight into drawing diagrams.
- Clarify First: Never assume you know the requirements. Spend the first 5 minutes defining functional scope and non-functional constraints.
- Let Scale Guide Your Design: Use back-of-the-envelope estimations to calculate read-to-write ratios. A 100:1 ratio immediately signals a read-heavy system requiring caching and read replicas.
- APIs Dictate Storage: Defining your API endpoints early clarifies exactly what data models and storage systems (e.g., relational databases vs. object storage) you need.
- Address the Celebrity Problem: Understand the trade-offs between Push (Fan-out on Write) and Pull (Fan-out on Read) models for feed generation.
- Design for Failure: Always assume your primary database will bottleneck as traffic scales. Be prepared to introduce caching (Redis/Memcached) and database sharding.