System Design Interview Prep

Comprehensive reference for system design interview prep covering essential concepts, practical examples, and production best practices.

System design interviews test your ability to turn a vague requirement into a robust, scalable, maintainable system under time pressure. You’re expected to design a real-world service—like a URL shortener, social media feed, or real-time chat—starting from a single sentence. This guide walks you through the process of preparing for and executing such interviews, with precise, reusable techniques, patterns, and common pitfalls.

Planning Your Approach

Structure the Problem Statement

Begin by extracting clear requirements from the interview prompt. Repeat the problem aloud. Identify:

Write down:

Use the 5 Ws framework:

Prioritize Requirements

Rank features by value and complexity. Use the MoSCoW method:

Example: For a photo-sharing app:

This guides your design depth: spend more time on must-haves, sketch lightly on could-haves.

Designing the Data Model

Define Entities and Relationships

Sketch a conceptual data model using entity-relationship notation. Use plain text or a whiteboard.

Entities:

Relationships:

Choose Storage Strategy

Decide on the primary storage: relational database, document store, or key-value store.

For a feed-heavy app, relational is common:

CREATE TABLE posts (
    id BIGSERIAL PRIMARY KEY,
    user_id BIGINT NOT NULL REFERENCES users(id),
    content TEXT,
    created_at TIMESTAMPTZ DEFAULT NOW(),
    updated_at TIMESTAMPTZ
);

CREATE INDEX idx_posts_user_id ON posts(user_id);
CREATE INDEX idx_posts_created_at ON posts(created_at);

For high-read, low-write workloads (e.g., user profiles), document store (e.g., MongoDB) may be better:

{
  "user_id": 12345,
  "name": "Alice Chen",
  "email": "[email protected]",
  "profile": {
    "bio": "Software engineer focused on distributed systems.",
    "location": "San Francisco"
  },
  "followers": [6789, 101112],
  "created_at": "2023-05-10T14:23:00Z"
}

Use denormalization to reduce joins:

Handle Schema Evolution

Plan for schema changes without downtime.

Example: adding a thumbnail_url to Posts:

Designing the API Layer

Define HTTP Endpoints

Use REST conventions. Use standard status codes:

Example endpoints:

GET /api/posts
GET /api/posts/{id}
POST /api/posts
PUT /api/posts/{id}
DELETE /api/posts/{id}
GET /api/users/{id}/feed
POST /api/posts/{id}/like
GET /api/posts/{id}/comments

Version the API

Use URL-based versioning:

Include version in response headers:

HTTP/1.1 200 OK
Content-Type: application/json
X-API-Version: 2.1

Implement Authentication and Authorization

Use JWT (JSON Web Tokens):

JWT payload:

{
  "user_id": 12345,
  "name": "Alice Chen",
  "email": "[email protected]",
  "exp": 1700000000,
  "iat": 1699990000,
  "scope": ["read", "write"]
}

Use scopes for fine-grained permissions:

Handle Rate Limiting

Apply token bucket algorithm:

Response:

{
  "error": "Too Many Requests",
  "message": "Rate limit exceeded",
  "retry_after": 60
}

Designing the Architecture

Choose a Deployment Strategy

Use microservices for complex systems.

Split the system into services:

Each service runs independently, with its own database.

Use API gateway to route requests:

Design Data Flow

Sketch the request path from client to database.

Example: fetching a feed:

  1. Client sends GET /api/users/12345/feed
  2. API gateway routes to Feed service
  3. Feed service:
  1. Feed service caches result in Redis for 10 minutes
  2. Client renders feed

Use caching strategy:

Handle Scalability and Failure

Scale Out the Database

Use read replicas:

Use database sharding:

Use consistent hashing to distribute data across shards.

Handle High Traffic

Use load balancer (e.g., Nginx, HAProxy) to distribute requests across service instances.

Deploy multiple instances behind a load balancer:

upstream post_service {
    server 10.0.1.10:8080;
    server 10.0.1.11:8080;
    server 10.0.1.12:8080;
}

server {
    listen 80;
    location /api/posts {
        proxy_pass http://post_service;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

Use connection pooling in database clients.

Manage Failures

Design for partial failures:

Use health checks:

Example health check response:

{
  "status": "healthy",
  "database": {
    "connected": true,
    "latency_ms": 12
  },
  "cache": {
    "connected": true,
    "hit_rate": 0.94
  },
  "uptime_seconds": 3642,
  "timestamp": "2023-10-15T10:30:00Z"
}

Deploy the System

Use containerization with Docker:

FROM golang:1.21-alpine
WORKDIR /app
COPY . .
RUN go build -o main main.go
EXPOSE 8080
CMD ["./main"]

Use Docker Compose for local development:

version: '3.8'
services:
  api-gateway:
    build: ./api-gateway
    ports:
      - "80:80"
    depends_on:
      - post-service
      - user-service
  post-service:
    build: ./post-service
    ports:
      - "8080:8080"
    environment:
      - DB_HOST=postgres
      - REDIS_HOST=redis
    depends_on:
      - postgres
  postgres:
    image: postgres:15
    environment:
      POSTGRES_DB: app
      POSTGRES_USER: user
      POSTGRES_PASSWORD: password
    volumes:
      - pgdata:/var/lib/postgresql/data
  redis:
    image: redis:7
    ports:
      - "6379:6379"
volumes:
  pgdata:

Evaluating Your Design

Present with Clarity

Use whiteboard or slides:

Justify Tradeoffs

Answer: “Why did you choose this?”

Examples:

Anticipate Questions

Prepare for common follow-ups:

Practice answering:

Handle Feedback

Listen carefully. Refine your design based on feedback.

If asked, “Can you make the feed update in real time?”:

Common Pitfalls and Sharp Edges

Confusing Caching Layers

Misunderstanding Load Balancing

Overlooking Failures

Missing Key Metrics

Use logging and monitoring:

{
  "timestamp": "2023-10-15T10:30:00Z",
  "trace_id": "a1b2c3d4",
  "service": "feed-service",
  "method": "GET",
  "path": "/api/users/12345/feed",
  "status": 200,
  "duration_ms": 142,
  "user_id": 12345,
  "num_posts": 25
}

Deploying Without Rollback

Always prepare rollback plan:

Final Checklist

This guide is not just a template—it’s a playbook for building confidence and clarity in every system design interview.

This page was rewritten on 18 October 2026. It replaced a templated version that was not specific to its own title. How these pages are written and checked. If anything here is wrong, tell us at [email protected] and we will correct it.