System Design Fundamentals
Core concepts for designing scalable distributed systems load balancing, caching, database sharding, and message queues.
publishedsystem-design, distributed-systems, architecture, backend
Load Balancing
Strategies
- Round Robin simple, no intelligence
- Least Connections routes to server with fewest active connections
- Weighted factors in server capacity
- IP Hash consistent routing for session affinity
Layers
- L4 (Transport) TCP/UDP level, faster, less intelligent
- L7 (Application) HTTP level, can route based on path/headers
Caching
Cache Strategies
- Cache-Aside app checks cache first, falls back to DB
- Write-Through writes go to cache and DB simultaneously
- Write-Behind writes go to cache, async flush to DB
- Read-Through cache loads from DB on miss
Cache Invalidation
The two hard problems in computer science:
- Cache invalidation
- Naming things
- Off-by-one errors
Use TTL-based expiration as the default. Event-driven invalidation for critical consistency.
Database Scaling
Vertical
Bigger machine. Simple. Limited.
Horizontal (Sharding)
- Hash-based consistent hashing for even distribution
- Range-based partition by date ranges or ID ranges
- Directory-based lookup table for shard mapping
Replication
- Primary-Replica writes to primary, reads from replicas
- Multi-Primary complex conflict resolution
- Trade-off: consistency vs. availability (CAP theorem)
Message Queues
When to use:
- Decouple services
- Handle traffic spikes (buffering)
- Async processing (emails, reports, exports)
- Event-driven architectures
Kafka high throughput, durable, ordered
RabbitMQ flexible routing, simpler operations
Redis Streams lightweight, good for simple queues
Key Principles
- Design for failure everything will fail
- Scale reads and writes independently
- Prefer eventual consistency when possible
- Measure before optimizing
- Simple architectures > clever architectures