Reference · gazar.dev ← All cheat sheets

System design · scaling data

The data-at-scale cheat sheet.

When one machine stops being enough, you have three moves: shard the data, replicate it, or cache it. This sheet shows, for every real database, how you scale it for reads vs writes, what you reach for, and the trade-off you take on. Companion to S4 · Data at Scale: Sharding, Replication, Caching.

01

First question: reads or writes?

Before any tool, diagnose. The fix depends entirely on whether too many reads or too many writes are the pain. Get this wrong and you open a one-way door you did not need.

R

Reads hurt

Pages are slow, the DB is busy serving the same queries. Fix with read replicas and a cache. Cheap, reversible, huge wins.

W

Writes hurt

One machine can’t absorb the write rate or hold the data. Bigger box first, then shard. Only sharding truly scales writes.

The trap

Sharding a read problem. Most teams that “need to shard” had a reads problem a replica or a cache would have fixed in an afternoon, without the permanent cost of a shard key.

02

The scaling ladder

Climb in order. Each rung is cheaper and less risky than the next. Do not jump to the top.

RungMoveHelpsNew cost
1Bigger box (vertical)reads & writesnone, until the ceiling; then it stops
2Read replicasreadsreplica lag, stale reads
3Cachereadsinvalidation, staleness, stampedes
4Shard (horizontal)writesone-way door, cross-shard queries hard

Vertical is boring and frequently correct. A read replica or cache buys years. Sharding is the last resort, not the first.

03

Three moves, side by side

Sharding, replication, caching. Each removes a bottleneck and hands you a caveat. Name both.

MoveWhat it isBuys youCosts youCaveat to name
Shardingsplit different rows across machineswrite & storage headroomcross-shard joins & transactions get hardthe shard key is forever
Replicationkeep the same data on several machinesread scale or staying upcopies lag the leaderreads can be stale
Cachinga fast copy of an answer you already computedhuge read relief, low latencyinvalidation & stampedesdata can be stale

Sharding vs replication, the one-line difference

Sharding splits different data across machines (for write/size scale). Replication copies the same data onto several machines (for read scale or availability). Most real systems do both.

04

How to scale each database

The real products, and the lever you actually pull. Each card: reads how to scale reads, writes how to scale writes, lever the main mechanism, trade-off what it costs.

PostgreSQLrelational
Reads
Streaming read replicas + a Redis cache + PgBouncer pooling. Scales reads almost linearly.
Writes
One primary takes all writes. Vertical first, then declarative partitioning; shard with Citus only when truly forced.
Lever
Replicas for reads; partitioning / Citus for writes.
Trade-off
Replicas lag (stale reads). Sharding loses easy cross-shard joins and transactions.
MySQL / MariaDBrelational
Reads
Binlog read replicas, route reads with ProxySQL, plus a cache.
Writes
One primary; Vitess for horizontal sharding once a single box can’t keep up.
Lever
Replicas for reads; Vitess for writes.
Trade-off
Replica lag; Vitess is operationally heavy and cross-shard queries get hard.
MongoDBdocument
Reads
Replica-set secondaries (set a read preference) + cache for hot aggregates.
Writes
Built-in sharding on a shard key (hashed or ranged); Mongo splits and balances chunks.
Lever
Sharding for writes; secondaries for reads.
Trade-off
Shard key is near-permanent; a bad one means a jumbo chunk / hot shard, and cross-shard reads scatter-gather.
Rediskey-value · in-memory
Reads
Replicas serve reads; client-side caching for the hottest keys.
Writes
Redis Cluster splits keys across 16,384 hash slots; or simply add RAM (it is memory-bound).
Lever
Cluster for write/memory scale; replicas for reads.
Trade-off
Multi-key ops break across slots; async replication can lose recent writes on failover. It is a cache, not your source of truth.
Cassandra / ScyllaDBwide-column
Reads
Add nodes; tune consistency per query (ONE, QUORUM). Reads scale with the cluster.
Writes
Masterless ring: every node takes writes. Add nodes and write throughput scales linearly.
Lever
Just add nodes (consistent-hashing ring, no single master).
Trade-off
Query-first tables, no joins, no ad-hoc. Eventual consistency. A bad partition key = a hot partition.
DynamoDBmanaged KV / document
Reads
DAX cache, GSIs for new patterns, eventually-consistent reads, global tables for multi-region.
Writes
Auto-sharded by partition key; capacity scales on-demand with zero ops.
Lever
Managed auto-scaling; the work is choosing the partition key.
Trade-off
A skewed key = a hot partition. Access patterns must be known up front; each GSI adds cost.
Elasticsearch / OpenSearchsearch · derived
Reads
Replica shards add read throughput and HA; add nodes to spread query load.
Writes
Primary shards split the index across nodes; more shards = more write parallelism.
Lever
Primary shards (writes) + replica shards (reads).
Trade-off
A derived store, near-real-time not consistent. Shard count is fixed at index creation; changing it means a reindex. RAM-hungry.
ClickHouseOLAP · columnar
Reads
Columnar scans + sharding & replication via distributed tables; aggregates over billions of rows in seconds.
Writes
Batch inserts (append-friendly). Feed it from an event stream, not row-by-row.
Lever
Shard + replicate; ingest in batches.
Trade-off
Update- and delete-hostile. Not for per-request OLTP reads or writes.

Pattern across the table: reads almost always scale with replicas + a cache; writes scale with sharding (built-in for Mongo / Dynamo / Cassandra, bolt-on via Citus / Vitess for Postgres / MySQL). Redis and the derived stores (Elastic, ClickHouse) are about choosing the right copy, not the source of truth.

05

Sharding quick reference

Splitting rows across machines. The shard key is the one decision that matters, and you live with it for years.

StrategySplits byRange readsHot-spot riskRebalancing
Rangevalue bands (A–M, N–Z)easyhigh — new data clumpssplit a band
Hashhash(key) → bucketlostlow — spreads evenlyhard — use a ring
Directorya lookup table maps key → shardflexibleyou control itflexible — extra hop

Choosing a shard key

  • Even spread — high-cardinality, no single value dominates (good: user_id, tenant_id; bad: country, status, a date).
  • In your common query — if the key is in the WHERE, one shard answers; if not, every query fans out to all of them.
  • Stable — you cannot move a row by editing its key.
  • Skew fixes — split a hot value with a suffix, or give the whale its own shard.
06

Replication quick reference

Copies of the same data, for read scale or for staying up. Two choices define it: wait for copies or not, and one writer or many.

ChoiceOptionProConUse when
Sync?Synchronousno loss on failoverslower writes; one slow copy stalls allmoney, one sync follower
Asynchronousfast writescan lose the last few secondsdefault for most data
Writers?Leader-basedsimple, orderedfailover gap, single writeralmost everything
Leaderless (quorum)always availableyou resolve write conflictsDynamo, Cassandra, multi-region

Replication lag: the bug to expect

Async copies are always a little behind. The classic symptom is read-your-writes: a user posts something, the next read hits a lagging copy, and it’s “gone.” Fix: read a user’s own recent writes from the leader, everything else from replicas. Always monitor the lag.

07

Caching quick reference

A fast copy of an answer, kept close. Layers (browser → CDN → app/Redis → DB); answer as early as you can. The pattern decides who fills it.

PatternHow it fillsWrite speedMain risk
Cache-asideapp checks cache; on miss reads DB and stores itnormalstale until TTL; first read is slow
Write-throughevery write updates cache and DBslower writesalways fresh, but caches unread data
Write-behindwrite to cache now, flush to DB laterfastestdata lost if cache dies before flush

Invalidation: the genuinely hard part

Two strategies, and most bugs come from mixing them. TTL (time-based): trust it for N seconds, simple, wrong for up to the TTL. Explicit (event-based): delete on change, fresh, but you must catch every write path. Don’t promise “fresh”, promise a named staleness window.

08

Failure modes & the repeatable move

What breaks first, the four traps, and the four-sentence move that keeps you honest.

What breaks first

  • Hot shard — one machine gets all the traffic (skew).
  • Replication lag — users miss their own writes.
  • Failover gap — leader dies, a brief no-writer window.
  • Thundering herd — a hot key expires, everyone stampedes.
  • Stale cache — a missed invalidation serves wrong data for ages.

The four traps

  • Sharding too early — a one-way door when a bigger box had years left.
  • A shard key you can’t defend — convenient, hot-spots day one.
  • “Replicas are consistent” — forgetting lag, chasing a vanishing write.
  • Cache with no invalidation story — silently serving stale data.

The repeatable move

1. name the bottleneck (reads? writes?)
2. pick the move (replica / cache / shard)
3. name what it buys
4. own what it costs

“Writes won’t fit on one box, so I shard by tenant_id. That buys linear write headroom. It costs me: big tenants run hot, and cross-tenant reports get hard.” That is a staff answer. “I’d add Cassandra” is a reflex.

Companion to S4 · Data at Scale: Sharding, Replication, Caching. Further reading: System Design Primer · MongoDB sharding · Redis Cluster scaling · DynamoDB partition keys.