Script Valley
System Design: APIs, Caching & Scalability
Scalability PatternsLesson 3.3

Database scaling: read replicas and sharding explained

read replicas, replication lag, write path vs read path, horizontal sharding, shard key selection, cross-shard queries, consistent hashing

Database scaling: read replicas and sharding explained

Read replicas and sharding

The Database Bottleneck

Your application servers scale horizontally but they all hit the same database. The database becomes the bottleneck. Two strategies address this at different scales: read replicas and sharding.

Read Replicas

Replicate the primary database to one or more read-only replicas. Route SELECT queries to replicas and writes to the primary. Most applications are read-heavy (80%+ reads), so this buys significant headroom.

const write = new Pool({ host: 'primary.db' });
const read  = new Pool({ host: 'replica.db' });

const getUser  = (id)   => read.query('SELECT * FROM users WHERE id=$1', [id]);
const saveUser = (data) => write.query('INSERT INTO users...', data);

Caveat: replication is asynchronous. A user who just updated their profile might read stale data for milliseconds to seconds. For reads that must be consistent after a write, query the primary.

Sharding

Partition data across multiple database instances by a shard key such as user_id mod N. Allows near-infinite horizontal write scaling. Costs: cross-shard queries are complex, changing the shard count requires redistributing data, and JOINs across shards are expensive. Use consistent hashing to minimize data movement when adding shards. Exhaust vertical scaling, read replicas, and caching before considering sharding.

Up next

What is a CDN and how does it reduce latency

Sign in to track progress

Database scaling: read replicas and sharding explained โ€” Scalability Patterns โ€” System Design: APIs, Caching & Scalability โ€” Script Valley โ€” Script Valley