Chapter 12: Database Scaling — Replication, Sharding, Read Replicas
Scaling Strategy Progression
1. Optimize queries + indexes (free!)
2. Vertical scaling (bigger machine)
3. Read replicas (scale reads)
4. Caching layer (reduce DB load)
5. Sharding (scale writes + storage)
Do them IN ORDER. Most systems never need step 5.
Read Replicas
Writes ──► Primary DB ──replication──► Replica 1 (reads)
──► Replica 2 (reads)
──► Replica 3 (reads)
App routes: writes → primary, reads → any replica
Scales read throughput linearly with replica count.
Trade-off: replication lag (reads may be slightly stale)
Sharding (Horizontal Partitioning)
Shard by user_id:
user_id % 4 = 0 → Shard 0
user_id % 4 = 1 → Shard 1
user_id % 4 = 2 → Shard 2
user_id % 4 = 3 → Shard 3
Each shard is an independent database holding 25% of data.
Scales both reads AND writes.
Sharding Challenges
- Cross-shard queries: JOINs across shards are very expensive
- Rebalancing: adding shards requires moving data
- Hot shards: uneven distribution (celebrity user on one shard)
- Transactions: ACID across shards requires distributed transactions
Choosing a Shard Key
| Key | Pro | Con |
|---|---|---|
| user_id | All user data on one shard | Celebrity users create hot shards |
| geographic region | Data locality | Uneven region sizes |
| hash(id) | Even distribution | Range queries hit all shards |
| time-based | Old data archivable | Recent shard gets all writes |
⚠️ Sharding is a Last Resort
Sharding adds enormous complexity. A single PostgreSQL instance with proper indexes handles millions of rows and thousands of QPS. Exhaust all other options (indexes, caching, read replicas, vertical scaling) before sharding.
Key Takeaways
- Scale reads: read replicas (simple, linear scaling)
- Scale writes: sharding (complex, last resort)
- Optimize first: indexes, query tuning, caching before scaling hardware
- Shard key choice is critical — determines query patterns and hot spots
- Most systems never need sharding — don't over-engineer