System Design Fundamentals · The Data Layer
Replication and Sharding
A single database server eventually runs out of capacity in one of two ways: it can't keep up with reads, or it can't keep up with writes (or store all the data). Each has a different fix.
Replication — fixes read capacity and availability
Copy the full dataset onto multiple machines. The classic setup is primary-replica: all writes go to one primary, which streams changes to one or more read replicas.
writes
↓
┌─────────┐
│ Primary │
└────┬────┘
replication stream
┌──────────┼──────────┐
↓ ↓ ↓
┌─────────┐┌─────────┐┌─────────┐
│Replica 1││Replica 2││Replica 3│ ← reads
└─────────┘└─────────┘└─────────┘
This solves two problems at once: read traffic can be spread across replicas (horizontal read scaling), and if the primary dies, a replica can be promoted, giving you availability. It does not solve write capacity — every write still goes through one primary — and replication is typically asynchronous, meaning replicas can briefly lag behind (more on why that's often an acceptable trade-off in the next section).
Sharding — fixes write capacity and storage size
Split the dataset itself across multiple databases, each holding a subset of the rows, based on a shard key.
writes for user 1-1000 writes for user 1001-2000
↓ ↓
┌─────────┐ ┌─────────┐
│ Shard A │ │ Shard B │
└─────────┘ └─────────┘
Now write capacity scales with the number of shards, since each shard only handles its own slice of traffic. The hard part is picking the shard key — a bad key creates a "hot shard" that gets disproportionate traffic (e.g. sharding a social app by signup date means all of today's active users hit one shard). A good shard key distributes both storage and load evenly, and ideally keeps data that's queried together on the same shard, since cross-shard queries (and especially cross-shard transactions) are expensive and often require the application to stitch results together itself.
Replication and sharding are usually combined, not chosen between: shard for write/storage scale, then replicate each shard for read scale and availability.