System Design Interview Guide 2026: Complete Preparation Framework
Master system design interviews with our complete guide. Learn the framework, common topics, and real-world examples.
Why System Design Interviews Matter
System design interviews are the most important part of mid-level and senior SDE interviews. They test your ability to think holistically about software systems. Unlike coding interviews where you solve algorithmic puzzles, system design interviews evaluate how you approach open-ended problems, make architectural decisions, and communicate trade-offs under pressure.
At Amazon specifically, system design interviews form a core part of the Loop. Interviewers assess your ability to design systems that are customer-obsessed, think big, and deliver results. The bar raiser will be watching for how you handle ambiguity — a skill that maps directly to the Leadership Principle of Bias for Action.
What Interviewers Look For
- Technical depth: Understanding of distributed systems concepts, including CAP theorem, consensus protocols, and failure modes
- Communication: Explaining complex ideas clearly, drawing diagrams that others can follow, and structuring your thoughts verbally
- Trade-off analysis: Balancing competing requirements like consistency vs availability, cost vs performance, and simplicity vs flexibility
- Practical experience: Real-world problem-solving ability — not just textbook knowledge but understanding of what breaks in production
- Problem decomposition: Breaking a large problem into manageable sub-problems and tackling them systematically
The System Design Framework
The 45-minute interview window is tight. Every minute counts. Here is a proven framework with specific time allocations that top performers use.
Step 1: Clarify Requirements (5 minutes)
Always ask questions before designing. This is the single most important step. Jumping into architecture without clarifying requirements is the number one mistake candidates make.
Functional Requirements:
- What are the core features? List them explicitly — you will scope down to 2-3 later
- What is the primary use case? Is this read-heavy, write-heavy, or balanced?
- Who are the users? Consumers, internal teams, or third-party services?
- What are the edge cases? Think about abuse, data corruption, and partial failures
Non-Functional Requirements:
- What is the expected scale? (users, QPS, storage) — be specific: 10M daily active users vs 1B is a fundamentally different system
- What is the latency requirement? Sub-100ms for real-time vs seconds for batch processing
- What is the availability target? 99.9% (8.76 hours downtime/year) vs 99.99% (52 minutes/year) changes every design decision
- What is the consistency model? Strong consistency (banking) vs eventual consistency (social media) vs read-your-writes (messaging)
Quick Tip: Write down the requirements on the whiteboard. This shows structured thinking and creates a reference point throughout the interview.
Step 2: High-Level Design (10 minutes)
Draw the major components. Start broad and add detail progressively.
Client -> Load Balancer -> API Servers -> Cache -> Database
-> Message Queue -> Async Workers
-> Analytics Pipeline
Components to Include:
- Load Balancer: Distribute traffic using round-robin, least connections, or consistent hashing
- API Servers: Stateless services that handle business logic — horizontally scalable by design
- Cache: Redis or Memcached to reduce database load for hot data
- Database: Primary storage — choose SQL for strong consistency, NoSQL for horizontal scaling
- Message Queue: Kafka or SQS for async processing and decoupling services
- CDN: Edge caching for static assets and geographically distributed users
Communication Patterns:
- Synchronous (HTTP/gRPC) for real-time request-response
- Asynchronous (message queue) for fire-and-forget or long-running tasks
- Event-driven (Kafka) for real-time data pipelines and cross-service communication
Step 3: Deep Dive (15 minutes)
Focus on the most interesting or challenging part of the system. This is where you demonstrate technical depth. The interviewer will often guide you here, but be prepared to identify the hard problems yourself.
Example: URL Shortener Deep Dive
Hashing Strategy:
Option 1: MD5 Hash + Base62
- MD5 produces 128-bit hash
- Take first 7 characters
- Base62 encoding (a-z, A-Z, 0-9)
- Result: 6-8 character short URL
- Problem: Collisions possible, need retry logic
Option 2: Counter + Base62
- Auto-increment counter
- Base62 encode the counter
- Guaranteed uniqueness
- Requires coordination in distributed system (e.g., ZooKeeper or database sequence)
Option 3: Pre-generated Keys
- Generate millions of unique keys offline
- Store in a key service
- Fast lookup, no collision risk
- Trades storage for compute
Read Path vs Write Path:
Write Path: Client -> API -> Generate Key -> Store (URL, key) -> Return short URL
Read Path: Client -> API -> Lookup Key in Cache -> If miss, lookup in DB -> Redirect (301/302)
301 vs 302 Redirect: Use 302 (temporary) so the browser hits your server every time, giving you analytics data. Use 301 (permanent) if you want to reduce server load by letting browsers cache the redirect.
Step 4: Wrap Up (5 minutes)
Discuss trade-offs and improvements:
Trade-offs:
- Strong consistency vs availability (CAP theorem)
- Latency vs storage cost (caching more data reduces latency but increases cost)
- Complexity vs simplicity (microservices vs monolith)
Monitoring and Operations:
- What metrics would you monitor? QPS, error rate, latency percentiles (p50, p95, p99), cache hit ratio
- What are the failure modes? Database failure, cache eviction storm, cascading failures
- How do you handle data growth? Archival strategy, data retention policies
Common System Design Topics
1. URL Shortener
Key Concepts: Hashing, Base62, Caching, Analytics, Rate Limiting
Scale Estimation:
- 100M URLs stored
- 1B redirects/day = ~12K QPS
- Each URL: ~500 bytes
- Total storage: ~50GB (fits in a single database)
- Read-to-write ratio: 100:1 (read-heavy, perfect for caching)
Database Schema:
table: urls
short_url: VARCHAR(7) PRIMARY KEY
original_url: VARCHAR(2048)
created_at: TIMESTAMP
expires_at: TIMESTAMP (nullable)
user_id: BIGINT (nullable)
Caching Layer: Use Redis with TTL matching URL expiration. Cache the top 20% of URLs that handle 80% of traffic (Pareto distribution). Implement cache warming on deployment to avoid cold-start thundering herd.
Collision Handling: On collision, append a random character and re-hash. Store a collision counter to monitor hash distribution quality.
2. Rate Limiter
Key Concepts: Token Bucket, Sliding Window, Distributed Counting, Redis Atomic Operations
Algorithms:
| Algorithm | Pros | Cons | Best For |
|---|---|---|---|
| Token Bucket | Smooth rate, allows bursts | Complex implementation | API rate limiting |
| Sliding Window Log | Accurate counting | Memory intensive (stores timestamps) | Audit-critical systems |
| Sliding Window Counter | Good accuracy, low memory | Approximate | General purpose |
| Fixed Window | Simple, low memory | Boundary burst problem | Low-stakes limiting |
Distributed Rate Limiting with Redis:
-- Token Bucket in Redis
MULTI
DECRBY rate:{user_id}:tokens 1
EXPIRE rate:{user_id}:tokens 3600
EXEC
-- Sliding Window Counter
ZADD rate:{user_id} {timestamp} {unique_request_id}
ZRANGEBYSCORE rate:{user_id} {window_start} {window_end}
ZREMRANGEBYSCORE rate:{user_id} 0 {window_start}
Edge Cases:
- What happens when Redis is down? Fall back to local rate limiting with reduced thresholds
- How to handle rate limit across multiple services? Centralized rate limiter service or distributed coordination via Redis
- Client-side vs server-side: Always enforce server-side; client-side is cosmetic only
3. Chat System
Key Concepts: WebSockets, Message Ordering, Presence, End-to-End Encryption
Architecture:
Clients
|
v
WebSocket Gateway (Connection Manager)
| |
v v
Message Router Presence Service (Redis)
|
+---> Message Queue (Kafka) for fan-out
|
+---> Message Storage (Cassandra for write-heavy workload)
|
+---> Push Notification Service (APNS/FCM)
Message Ordering: Use a combination of server-assigned sequence numbers and client timestamps. For group chats, partition messages by chat_id to ensure ordering within a partition.
Delivery Guarantees:
- At-most-once: Fire and forget, no retry — acceptable for notifications
- At-least-once: Retry until acknowledged, client deduplicates — standard for chat
- Exactly-once: Complex, use idempotency keys and transactional outbox pattern
Offline Messages: Store in a persistent queue (Cassandra or DynamoDB). On reconnection, deliver in order and mark as read. Use a separate offline message store indexed by user_id and timestamp.
Presence: Track online/offline status using Redis with TTL-based heartbeats. Publish presence events via Kafka for real-time updates across services. Handle edge cases like battery death (no disconnect message) gracefully.
4. News Feed
Key Concepts: Fan-out, Pull vs Push, Ranking, Deduplication
Fan-out Strategies:
| Strategy | Description | Use Case | Trade-off |
|---|---|---|---|
| Fan-out on write | Pre-compute feeds at post time | Users with few followers (<10K) | Write amplification, stale data |
| Fan-out on read | Compute feed at read time | Users with many followers (>10K) | High read latency, expensive |
| Hybrid | Both strategies based on follower count | Most social networks | Complex but optimal |
Feed Generation Algorithm:
1. Get list of users this person follows
2. For each followed user:
a. If fan-out-on-write: read pre-computed feed from cache
b. If fan-out-on-read: fetch recent posts, score, and sort
3. Merge results, deduplicate, apply ranking model
4. Return top N posts with metadata
Ranking Signals:
- Recency: Time since post creation
- Engagement: Likes, comments, shares weighted by recency
- Relationship: Interaction frequency between users
- Content type: Videos and images get higher weight than text
- Author authority: Verified accounts, historical engagement
Cassandra Schema for Feed Storage:
table: feed
user_id: BIGINT (partition key)
post_id: BIGINT (clustering key, DESC order)
author_id: BIGINT
content: TEXT
created_at: TIMESTAMP
engagement_score: FLOAT
5. E-commerce Checkout
Key Concepts: Inventory Management, Payment Processing, Idempotency, Saga Pattern
Checkout Flow:
1. Cart -> Order Creation
- Validate items and prices (prices may have changed)
- Check inventory availability
- Create order with PENDING status
- Reserve stock (optimistic locking with version field)
2. Payment Processing
- Idempotency key for retry safety
- Process payment with provider (Stripe, Adyen)
- Handle 3D Secure and SCA compliance
- Update order status to PAID or PAYMENT_FAILED
3. Inventory Update
- Confirm reservation after payment success
- Release if payment fails (TTL-based reservation expiry)
- Notify warehouse for fulfillment
4. Post-Checkout
- Send confirmation email
- Update analytics pipeline
- Trigger recommendation engine refresh
Saga Pattern for Distributed Transactions:
Order Saga Steps:
1. Reserve Inventory -> On Failure: Cancel (no-op)
2. Process Payment -> On Failure: Release Inventory
3. Confirm Order -> On Failure: Refund Payment, Release Inventory
4. Notify Customer -> On Failure: Log and retry
Each step has a compensating action that undoes the previous step.
Inventory Optimistic Locking:
UPDATE inventory
SET quantity = quantity - 1, version = version + 1
WHERE product_id = ? AND version = ? AND quantity > 0;
-- If affected rows = 0, someone else modified it. Retry or fail.
Scalability Patterns
Horizontal Scaling
Load Balancer Algorithms:
- Round Robin: Simple, equal distribution — good when all servers are identical
- Least Connections: Route to least busy server — better for variable request times
- IP Hash: Sticky sessions for stateful apps — use sparingly, limits scaling
- Weighted Round Robin: Route more traffic to powerful servers — good for heterogeneous fleets
Stateless Services: The key to horizontal scaling is making servers stateless. Store session data in Redis, not local memory. This lets you add or remove servers freely.
Database Scaling
Read Replicas:
Write -> Primary DB -> Read Replicas
-> Read Replicas
-> Read Replicas
Pros: Simple, improves read throughput by Nx (N = number of replicas)
Cons: Replication lag (10-500ms), read-your-writes issues
Solution: Route reads to primary immediately after write (session stickiness)
Sharding:
Data split across multiple databases by shard key
Shard by: user_id (hash-based), geographic region, or time range
Hash-based sharding: shard = hash(user_id) % num_shards
Range-based sharding: shard = region lookup table
Pros: Linear scale for writes, data locality
Cons: Cross-shard queries, rebalancing, hotspots
Mitigation: Use consistent hashing to minimize redistribution on resharding
Sharding Decision Tree:
Is your database read-bound?
-> Yes: Add read replicas first (simpler)
-> No: Continue
Is your dataset < 1TB?
-> Yes: Vertical scaling + read replicas may suffice
-> No: Consider sharding
Do you have hot keys or hotspots?
-> Yes: Use consistent hashing or application-level key salting
-> No: Hash-based sharding is straightforward
Partitioning Strategies:
- Hash Partitioning: Even distribution, good for均匀 workloads
- Range Partitioning: Good for time-series data, supports range queries
- List Partitioning: Good for categorical data (e.g., by country or region)
Caching Strategies
| Strategy | Description | Use Case | Invalidation |
|---|---|---|---|
| Cache-Aside | App checks cache first, loads from DB on miss | General purpose | Manual invalidation |
| Read-Through | Cache loads from DB transparently | Read-heavy, lazy loading | TTL-based |
| Write-Through | Cache and DB written together | Strong consistency needed | Automatic |
| Write-Behind | Cache written first, DB async | High write throughput | Complex |
| Refresh-Ahead | Cache proactively refreshes before expiry | Predictable access patterns | Proactive TTL |
Cache Invalidation Patterns:
- TTL-based: Simple, eventual consistency — good for non-critical data
- Event-based: Invalidate on write via Kafka event — strong consistency but complex
- Tag-based: Group cache entries by tag, invalidate entire group — useful for related data
Thundering Herd Problem: When a popular cache entry expires, thousands of requests hit the database simultaneously. Solutions:
- Mutex/Lock: Only one request refreshes the cache, others wait or get stale data
- Probabilistic refresh: Randomly refresh before expiry to spread load
- Stale-while-revalidate: Return stale data immediately, refresh in background
- Request coalescing: Deduplicate identical in-flight requests
Redis Cluster Architecture:
Client -> Redis Cluster (16384 hash slots distributed across nodes)
|
+---> Master Node 1 (slots 0-5460) -> Replica 1a, Replica 1b
+---> Master Node 2 (slots 5461-10922) -> Replica 2a, Replica 2b
+---> Master Node 3 (slots 10923-16383) -> Replica 3a, Replica 3b
Each key is assigned to a slot: slot = CRC16(key) mod 16384
CDN and Edge Caching
CDN Strategy:
- Static assets: JS, CSS, images — long TTLs (1 year), immutable filenames
- Dynamic content: API responses — short TTLs (seconds to minutes)
- Purge on deploy: Invalidate CDN cache on deployment for instant updates
- Geographic routing: Serve content from nearest edge location
Performance Optimization Techniques
Latency Reduction
- Multi-layer caching: L1 (in-memory, 1ms) -> L2 (Redis, 5ms) -> L3 (CDN, 20ms) -> Database (50-200ms)
- CDN: Serve static assets from edge locations — reduces latency from 200ms to 20ms for global users
- Connection Pooling: Reuse database connections — eliminates 5-10ms connection overhead per request
- Keep-Alive: Maintain HTTP connections — avoids TCP handshake (1-3 round trips)
- HTTP/2 Multiplexing: Send multiple requests over a single connection — eliminates head-of-line blocking
- Protobuf/MessagePack: Binary serialization — 2-10x smaller payloads than JSON
Throughput Optimization
- Batch Processing: Group 100 individual DB inserts into one bulk insert — reduces round trips from 100 to 1
- Async Processing: Move non-critical work to background queues — reduces request latency by 50-80%
- Parallel Processing: Fan-out requests to multiple services simultaneously — reduces tail latency
- Database Optimization: Proper indexes, query plans, connection pooling
- Denormalization: Pre-join data in read-optimized tables for complex queries
Database Query Optimization
Index Strategy:
- Composite indexes: Place high-selectivity columns first
- Covering indexes: Include all columns needed by the query to avoid table lookups
- Partial indexes: Index only rows meeting a condition (e.g., active users only)
Query Anti-Patterns to Avoid:
- SELECT * — fetches unnecessary columns, breaks covering indexes
- N+1 queries — use JOINs or batch loading
- Missing LIMIT on unbounded queries
- Functions on indexed columns (WHERE UPPER(name) = 'X') — prevents index usage
Common Pitfalls and How to Avoid Them
1. Over-engineering
Pitfall: Designing for 10M users when the requirement is 100K.
Solution: Start simple. Design for 10x current scale, then iterate. A monolith is fine for the first million users.
2. Ignoring Failure Modes
Pitfall: Only designing for the happy path.
Solution: For every component, ask: What happens when this fails? Plan for database outages, network partitions, cache failures, and dependent service degradation.
3. Single Points of Failure
Pitfall: Relying on a single database, single load balancer, or single-region deployment.
Solution: Add redundancy at every layer. Use multi-AZ deployments, database replicas, and multiple load balancers.
4. Not Measuring
Pitfall: Designing without metrics or monitoring.
Solution: Define SLIs (Service Level Indicators) upfront. Track p50, p95, p99 latency, error rates, throughput, and saturation metrics.
5. Skipping Trade-offs
Pitfall: Presenting one solution as the only option.
Solution: Always present 2-3 alternatives with pros and cons. Show the interviewer you can think critically about constraints.
6. Ignoring Data Consistency
Pitfall: Assuming distributed transactions are simple.
Solution: Understand the CAP theorem trade-offs. Use the Saga pattern for distributed transactions. Accept eventual consistency where appropriate and document the consistency guarantees.
7. Not Handling Backpressure
Pitfall: Assuming the system can always handle the incoming load.
Solution: Implement backpressure mechanisms: rate limiting, circuit breakers, queue depth monitoring, and graceful degradation under load.
Real-World Case Studies
Case Study: Netflix — Chaos Engineering
Netflix pioneered Chaos Engineering with Chaos Monkey, which randomly kills production instances. This forces every service to be resilient to failure. Key lessons:
- Design for failure: Every component assumes it will fail
- Circuit breakers: Use Hystrix-style circuit breakers to prevent cascading failures
- Bulkhead pattern: Isolate failures so one bad service does not bring down the entire system
- Graceful degradation: Serve cached content when services fail rather than showing errors
Case Study: Uber — Geo-Sharding
Uber shards its database by geographic region so that ride requests are served by data centers near the rider. This reduces latency and allows regional compliance. Key lessons:
- Data locality: Keep data close to where it is accessed most frequently
- Consistent hashing: Minimize data movement when adding or removing shards
- Hot partition handling: Popular areas generate more traffic — use adaptive sharding or partition splitting
Case Study: Discord — Moving from Cassandra to ScyllaDB
Discord moved from Cassandra to ScyllaDB (a C++ rewrite of Cassandra) to reduce tail latency. They achieved 10x improvement at lower cost. Key lessons:
- Tail latency matters: p99 latency affects user experience more than average latency
- Technology evaluation: Re-evaluate stack decisions as requirements and technology evolve
- Migration strategy: Run dual-write during migration, validate data consistency, then cut over
Case Study: Twitter — Fan-out on Read vs Write
Twitter uses a hybrid fan-out approach. Most tweets are fanned out on write (pushed to follower timelines). Users with millions of followers use fan-out on read (pulled at request time). Key lessons:
- Identify outliers: A few users dominate traffic — design special handling for them
- Hybrid approaches: Combine strategies for different access patterns
- Pre-computation trade-offs: Pre-computing saves read time but costs write time and storage
Resources
- System Design Roadmap - Complete learning path
- Distributed Systems Topics - Core concepts
- Practice Problems - Coding practice
- SDE Interview Roadmap - Full interview preparation plan
- Coding Patterns - Patterns for the coding rounds
Continue Your Prep
Apply what you learned with our structured roadmaps and practice problems.