Skip to main content
Database Shardinglesson 2 of 4 · 3 min read

Picking a Shard Key

Two goals that fight

The shard key decides which shard owns each row. You are chasing two things at once: spread the load evenly, and keep each common query inside a single shard.

Those two goals fight each other, and the fight is where sharding projects go sideways.

Hash sharding runs the key through a hash and assigns by the result. Spread comes out even, which is why it is the default everywhere. What you give up is order. Neighbouring keys land on different shards, so any query for a range, everything from March, has to ask every shard.

Range sharding keeps ordered runs together instead, so time ranges and prefix searches stay on one machine. Its curse is the hot shard: when all your new data carries recent timestamps, every insert pounds the last shard while the rest hold cold history.

Directory sharding keeps a lookup table in the middle, so you can place any key on any shard. That buys easy rebalancing, and the price is a lookup service that must be fast, cached, and never down.

What most products pick

Pick the user for most consumer products, hashing on user or tenant, because one person's data stays together and nearly every query is about one person.

Then meet the celebrity. Hashing spreads keys evenly, not load, and one customer with 10,000 times the normal activity sits entirely on one unlucky shard. You fix it by splitting that one customer's rows across shards with a suffix, or by moving your handful of giants onto their own hardware. Every large system ends up doing one of these.

Choose with your query log open. List your ten busiest queries and check that each one can name its shard from the key alone. A shard key that turns your most common query into a question for every machine is not a key. It is a mistake with a schema.

the shape of it
Apphash(user_id)mod 3Shard 01/3 of usersShard 11/3 of usersShard 21/3 of usersuser 4217result 0result 1result 2
step 1 of 2
The hash spreads users evenly, and any one user's rows live on exactly one shard.

Worked example

Yuki's team shards a chat product by channel_id across 16 database instances. It works until a gaming company with 300,000 members concentrates its traffic in one announcements channel, and every message, read receipt, and reaction there lands on shard 11. That single channel becomes 25 percent of the cluster's writes; shard 11 runs at 90 percent CPU with p99 write latency of 900 ms while the other 15 shards idle near 20 percent. The short-term move is a bigger instance for shard 11 alone, which buys weeks. The durable fix changes the message key to channel_id plus a 10-day time bucket, the same shape Discord used for its message store, so a monster channel's history spreads across shards while any single conversation window still reads from one.