How to Scale a Database: Replication, Caching and Sharding

How to scale a database step by step: vertical vs horizontal, replicas and caching for reads, partitioning for writes, and combining partitions with replicas.

Beginner 4 min read · Updated

Sooner or later one database server isn't enough: too many reads, too many writes, or too much data. There are three main tools, each aimed at a different bottleneck: replication (copies, to scale reads), caching (hot data in memory, to scale reads further) and partitioning or sharding (split the data, to scale writes and storage). This page shows how they fit together; each has its own deep-dive page.

Vertical vs horizontal scaling

Vertical scaling is like upgrading your computer: add CPU, memory or disk to the one server. It's the quickest and easiest step, but it gets expensive, the biggest machines still have limits, and cloud providers only offer certain hardware sizes, so there's a ceiling. Horizontal scaling connects many machines to share the work: keep adding machines as needed, which is more flexible and usually cheaper at scale. Because of vertical scaling's ceiling, system designs almost always scale horizontally. See scalability.

Vertical: scale upHorizontal: scale outupgradeDB server8 coresBigger DB server64 cores, more RAMNode 1Node 2Node 3 …
Vertical scaling makes one machine bigger; horizontal scaling adds more machines that share the load.

Terminology: machines connected to work together form a distributed system, and each machine is a node. "Machine" and "node" mean the same thing in the rest of these guides.

Scaling reads with replication

Replication keeps extra copies of the data on other machines (replicas) and lets clients read from them, so more read requests can be served at once. The most common setup is single-leader (primary–replica) replication, the default in relational databases:

  • Writes: the client writes to the primary, which asynchronously sends each change to the read replicas.
  • Reads: the client can read from any replica.
asyncWritesReadsPrimaryReplica 1Replica 2
Single-leader replication: all writes go to the primary, which streams changes to replicas; reads spread across every copy.

Replication also gives redundancy (several copies, so a failed machine's traffic can be redirected with little disruption) and high availability (the service keeps running when some machines break). Multi-leader and leaderless replication are covered in replication.

Scaling reads with caching

A cache keeps frequently read data in fast storage, usually memory. The goal is for the cache to answer as many requests as possible and touch the database only on a miss. See caching.

1. get2. miss onlyApp serverCacheRedis / MemcachedDatabase
Cache in front of the database: hits are served from memory; only misses reach the database, and the result is stored for next time.

Scaling writes with partitioning (sharding)

Replicas copy all the data and every write still hits the one primary, so replication doesn't help writes. Partitioning (sharding) splits a table's rows across machines: each partition has the same schema but different rows. A write goes to just one partition, so write load (and storage) spreads over all of them, and adding machines adds capacity.

The field that decides where a row goes is the partition key. Since the goal is to spread write load, keys should distribute as evenly as possible. The simplest scheme hashes with MOD: partition = user_id % 4.

routeINSERT commentuser_id = 66 % 4 = 2Partition 0user 4, 8, 12 …Partition 1user 1, 5, 9 …Partition 2user 2, 6, 10 …Partition 3user 3, 7, 11 …
Hash partitioning with user_id % 4: each user's rows land on exactly one of four partitions.

Simple, but three problems appear quickly:

  1. Range queries: with hash partitioning, "all records with user_id between x and y" must ask every partition. Fine for IDs, painful for fields you count or scan by range (timestamps, prices).
  2. Hot partitions: in a social app where users comment on each other's profiles, partitioning comments by profile owner sends a celebrity's flood of comments to one partition, which runs far hotter than the rest. See hot partitions.
  3. Rebalancing: when partitions fill up and you add a 5th, % 4 no longer covers it. Switching to % 5 changes the partition of most keys, so data moves across all partitions. Consistent hashing fixes this.

Partitioning strategies, range vs hash keys and rebalancing are covered in sharding.

Partitioning and replication together

Real systems combine both for fault tolerance: each partition is copied to several nodes. A record lives in exactly one partition, but that partition lives on several nodes, and each node is the leader for some partitions and a follower for others. If a node fails, nodes holding replicas of its partitions keep serving.

P1P2P3Node 1P1 leader · P3 followerNode 2P2 leader · P1 followerNode 3P3 leader · P2 follower
Three nodes, three partitions, two copies each: every node leads one partition and follows another, so any single node can fail without losing data.

Summary and a typical order of moves

TechniqueWhat it doesScales
Vertical scalingBigger machineEverything, up to a ceiling
ReplicationCopies of the data on more machinesReads, plus availability
CachingFrequently used data in memoryReads (hot data)
Partitioning / shardingSplit data into pieces stored separatelyWrites and storage
  1. Optimize first: indexes, query fixes, connection pooling. See database optimization.
  2. Scale up the machine while it's cheap.
  3. Add a cache for hot reads, then read replicas.
  4. Split by function (separate databases per service or domain). See database per service.
  5. Shard when writes or data size outgrow one primary.

Where it’s used

Read-heavy web apps

A primary plus read replicas and Redis serve 100× more reads than writes.

Write-heavy feeds and chat

Messages partitioned by conversation or user across many nodes.

Global products

Replicas placed near users cut read latency; partitions keep each region's write load manageable.

Managed databases

Aurora, Cloud SQL and DynamoDB package replication, failover and partitioning behind one endpoint.

In an interview

  • Name the bottleneck first (reads, writes or storage), then the matching tool.
  • Reads: cache plus replicas, and mention replication lag. Writes: shard on a key that spreads load evenly.
  • Call out hot partitions, cross-shard queries and rebalancing as the costs of sharding.
  • Combine partitioning with replication so a node failure doesn't lose data.