System Design
Overview
System design covers the principles and patterns for building scalable, reliable, and maintainable distributed systems, a core topic in senior engineering interviews.
Key Concepts
Scalability
- Vertical scaling (scale up), bigger machine. Simple but has limits.
- Horizontal scaling (scale out), more machines. Requires stateless services.
CAP Theorem
A distributed system can guarantee at most 2 of 3:
- Consistency, every read gets the latest write.
- Availability, every request gets a response (not necessarily latest).
- Partition Tolerance, system works despite network partitions.
In practice: partition tolerance is required. Choose CP (e.g., HBase) or AP (e.g., Cassandra, DynamoDB).
Load Balancing
Distributes traffic across multiple servers:
- Round Robin, sequential distribution.
- Least Connections, route to server with fewest active connections.
- IP Hash, consistent routing based on client IP (session affinity).
- Layer 4 (TCP), faster, less context.
- Layer 7 (HTTP), routes based on URL, headers, cookies.
Caching
Client → CDN → Load Balancer → App Server → Cache (Redis) → Database
- Cache-aside (lazy loading), app checks cache first; on miss, loads from DB and populates cache.
- Write-through, write to cache and DB simultaneously.
- Write-behind, write to cache, async flush to DB.
- TTL, time-to-live; expiry for cached entries.
- Eviction policies, LRU, LFU, FIFO.
Databases
SQL vs NoSQL
| SQL (Relational) | NoSQL | |
|---|---|---|
| Schema | Fixed | Flexible |
| Scaling | Vertical (read replicas for reads) | Horizontal |
| ACID | Yes | Often eventual consistency |
| Best for | Complex queries, joins | High throughput, flexible data |
Database Patterns
- Read replicas, offload reads from primary.
- Sharding, partition data horizontally across multiple DBs.
- Connection pooling, reuse DB connections (HikariCP).
- Indexing, B-tree (range queries), Hash (equality), full-text.
Message Queues
Decouple producers from consumers, enable async processing:
- Kafka, high-throughput, durable, log-based, replay.
- RabbitMQ, flexible routing, lower throughput, message acknowledgement.
- SQS, managed, AWS-native, simple.
API Design
- REST, stateless, resource-based, HTTP verbs.
- GraphQL, client specifies exactly what data it needs.
- gRPC, binary protocol (Protobuf), high performance, streaming.
Rate limiting: Token bucket, leaky bucket, fixed/sliding window.
High Availability Patterns
- Circuit Breaker, stop calling a failing service; fallback response.
- Retry with backoff, exponential backoff + jitter.
- Bulkhead, isolate failures (thread pool per service).
- Health checks, liveness + readiness probes.
- Multi-region deployment, active-active or active-passive.
Interview Framework
For any system design question, follow:
- Clarify requirements, functional and non-functional (scale, latency, consistency).
- Estimate scale, DAU, QPS, storage.
- High-level design, components and data flow diagram.
- Deep dive, focus on the hard parts (DB schema, API design, bottlenecks).
- Identify tradeoffs, explain your choices.
Cheat Sheet
Scale: Vertical (bigger) | Horizontal (more)
CAP: Consistency | Availability | Partition Tolerance (pick 2)
Cache: Redis | CDN | Cache-aside | Write-through | TTL | LRU
Queue: Kafka | RabbitMQ | SQS
LB: Round Robin | Least Connections | Layer 4/7
HA: Circuit Breaker | Retry + Backoff | Health Checks | Multi-region
DB: Read replicas | Sharding | Connection pool | Indexing