Scaling Patterns
Vertical Scaling (Scale Up)
Add more CPU/RAM/disk to one machine. Simple, no code changes. Limited by hardware ceiling. Good first step. Examples: upgrading RDS instance, bigger VM.
Horizontal Scaling (Scale Out)
Add more machines. Requires stateless design or distributed state. Theoretically unlimited. Examples: adding web servers behind a load balancer.
Database Sharding
Split data across multiple DBs by a shard key (user_id, region). Each shard holds a subset. Challenges: cross-shard queries, rebalancing, hotspots.
Sharding Strategies
Hash-based: hash(key) % N — even distribution, hard to range query. Range-based: A-M shard1, N-Z shard2 — supports range queries, risk of hotspots. Directory-based: lookup table — flexible, extra hop.
Read Replicas
Write to primary, read from replicas. Scales reads linearly. Eventual consistency on replicas (replication lag). Works well for read-heavy workloads (95%+ reads).
CQRS
Command Query Responsibility Segregation. Separate write model (optimized for writes) from read model (optimized for queries). Enables independent scaling of reads vs writes.
Event Sourcing
Store events (facts) instead of current state. Rebuild state by replaying events. Full audit trail, temporal queries. Often paired with CQRS. Complexity cost is high.
Database Federation
Split databases by function (users DB, orders DB, products DB). Each scales independently. Challenges: cross-database joins, distributed transactions.
Connection Pooling
Reuse database connections instead of creating new ones. PgBouncer, ProxySQL. Essential when scaling app servers — DBs have limited max connections (~500-5000).
Scaling Sequence
1. Optimize queries + indexes. 2. Add caching (Redis). 3. Read replicas. 4. Vertical scaling. 5. CDN for static content. 6. Horizontal scaling + LB. 7. Sharding (last resort).