Sharding and partitioning in system design
Sharding splits one data set across several machines so that each holds and serves only part of it. It is how a design scales writes and storage beyond one server, and in an interview the decisions that matter are the shard key, the partitioning scheme, and what happens to queries, transactions and indexes that cross shards.
By Evin JohnPublished 8 min read
1. What sharding is
Sharding (horizontal partitioning) divides the rows or items of a data set into disjoint groups, called shards or partitions, and places each group on a different node. A routing step maps each key to its shard, so a request for one key goes to one machine. Every shard is usually also replicated, so a node failure loses no data. The difficulty is everything that does not fit one key: queries across many keys, transactions across shards, and moving data when the number of shards changes.
2. Why interviewers ask about it
Any prompt with large numbers eventually reaches the point where one database is not enough, and the interviewer wants to see how you split it. A good answer derives the need from the estimates, picks a shard key from the access pattern, and anticipates hot spots. A weak answer says "we shard the database" without a key, which leaves every hard question unanswered.
3. Partitioning, replication, and whether to shard at all
| Partitioning (sharding) | Replication | |
|---|---|---|
| What it does | Splits the data; each node holds a subset | Copies the same data to several nodes |
| What it scales | Write throughput and storage | Read throughput |
| What it protects against | Nothing on its own: losing a shard loses its subset | Node failure, and with copies in other zones, zone failure |
| Typical combination | N shards | Each shard kept as about 3 copies |
Sharding adds lasting complexity, so rule out the alternatives first: a larger machine, read replicas for read-heavy load, a cache for the hot set, archiving cold data, and moving unrelated tables into separate databases (functional partitioning). Shard when the estimates show one of these:
- Writes exceed one primary. Replicas do not help, because every replica still applies every write.
- The data outgrows one machine, or backups and restores of it take longer than you can tolerate.
- The working set no longer fits in memory and adding RAM to one server has stopped being practical.
For example, the URL shortener estimate reaches about 183 billion mappings and 90 TB over five years. That is a clear case. A service with 50 GB of data and 500 writes a second is not.
4. How keys map to shards
| Scheme | How it works | Strength | Weakness |
|---|---|---|---|
| Hash | Hash the key and map the hash to a shard | Spreads load evenly, including sequential keys | Range queries must ask every shard |
| Range | Each shard owns a contiguous range of keys (A to F, G to M...) | Efficient range scans; easy to split a range in two | Sequential keys such as timestamps send all new writes to the last shard |
| Directory | A lookup table records which shard holds each key or tenant | Total flexibility: move one big tenant to its own shard | The directory is an extra lookup and a critical service to keep available |
Going from 4 to 5 shards with shard = hash mod N:
a key stays put only if hash mod 4 == hash mod 5
in every 20 consecutive hash values, only 4 satisfy that (0, 1, 2, 3)
so 80% of keys move
Going from 4 to 5 nodes with consistent hashing (even load):
the new node takes over about 1/5 of the key space
so about 20% of keys move, all of them to the new nodeConsistent hashing places nodes and keys on the same hash ring; each key belongs to the first node clockwise from it. Adding or removing a node only affects the keys between it and its neighbor. With a single point per node the ring is uneven, so each physical node gets many points, called virtual nodes, often on the order of a hundred or more. Virtual nodes even out the load, let a more powerful machine take more points, and spread a failed node's keys across many survivors instead of dumping them on one neighbor.
A common practical alternative is a fixed number of logical partitions, far more than there are nodes. A key's partition never changes; rebalancing moves whole partitions between nodes. Redis Cluster, for instance, uses 16,384 hash slots. This gives the same small movement as consistent hashing with simpler bookkeeping, at the cost of choosing the partition count up front.
- App tier
- App servers
- Routing
- Router or client library
- Shard map in a config store
- Shards
- Shard 1: leader + 2 replicas
- Shard 2: leader + 2 replicas
- Shard N: leader + 2 replicas
5. Choosing a shard key, and hot partitions
- High cardinality: many distinct values, so the data can spread across many shards. Country code is a poor key; user ID is a good one.
- Even load, not just even data: a key whose values are equally common but unequally busy still creates hot shards.
- Matches the main query: the dominant request should carry the key so it touches one shard.
- Keeps together what changes together: data updated in one transaction should share a shard.
| Key | Spread | Main query (latest messages in a conversation) | Verdict |
|---|---|---|---|
| Conversation ID | Even, except very large groups | One shard | Good default |
| Sender's user ID | Even | A conversation's messages are scattered across shards | Poor fit for the main query |
| Timestamp (range) | All new writes on the newest shard | Scatter-gather | Hot spot |
| Message ID (hash) | Even | Scatter-gather | Spreads load but breaks locality |
Hot partitions and the celebrity problem. Even a good key has outliers: one account with tens of millions of followers, one viral post, one enormous customer. Partitioning by user ID puts all of that traffic on one shard. Remedies, roughly in order of effort:
- Cache and replicate the hot data so reads are spread over caches and replicas rather than one leader.
- Split the hot key. Write to
post:9#0topost:9#9at random and sum or merge the ten on read. Use it only for keys known to be hot, because every read now touches ten entries. - Treat outliers differently in the design, as feed systems do by not fanning out posts from very large accounts. See design Twitter.
- Isolate a huge tenant on its own shard, which a directory scheme makes straightforward.
6. Resharding, cross-shard work and secondary indexes
- Prefer moving partitions to changing the schemeWith many logical partitions or virtual nodes, adding capacity means copying some partitions to the new node, catching up on changes, then switching ownership in the shard map.
- For a new key or scheme, dual-writeWrite to both the old and new layout, backfill historical data into the new one, and compare reads from both (shadow reads) until they agree.
- Switch reads, then stop old writesMove reads to the new layout behind a flag you can turn back, then stop writing the old one and remove it.
- Throttle the copyMoving data competes with live traffic. Rate-limit it and avoid peak hours, and keep routing correct during the move, for example by redirecting requests for a partition in transit.
Cross-shard queries use scatter-gather: send the query to every shard and merge the results. Latency is set by the slowest shard, and that compounds: if each shard is slow 1% of the time, a query touching 100 shards meets at least one slow shard about 63% of the time (1 - 0.99^100 ≈ 0.63). Avoid scatter-gather on hot paths by choosing a key that matches the query, or by keeping a second copy of the data partitioned another way.
Cross-shard transactions. Two-phase commit makes a change on several shards atomic, but participants hold locks while they wait, and a coordinator failure at the wrong moment leaves them blocked. Distributed SQL systems run two-phase commit over consensus-replicated shards to reduce that risk, at a latency cost. Many designs avoid the problem: keep data that changes together on one shard, or use a saga, a series of local transactions with compensating steps if a later one fails, accepting that intermediate states are visible. The payment system walk-through covers this trade-off.
| Local index (partitioned by document) | Global index (partitioned by term) | |
|---|---|---|
| Where it lives | Each shard indexes only its own rows | The index is itself sharded by the indexed value |
| Writes | Cheap: one shard updates its own index | One write may update index entries on other shards, so global indexes are often updated asynchronously |
| Reads by indexed value | Scatter-gather to every shard | One index shard, then fetches from the data shards |
| Freshness | Consistent with the shard's data | May lag the data; DynamoDB's global secondary indexes, for example, are eventually consistent |
7. How it shows up in common prompts
| Prompt | Shard key | What to watch |
|---|---|---|
| URL shortener | Hash of the short code | Range partitioning by code would put every new sequential code on one shard |
| Conversation ID | Very large groups; a user's conversation list needs its own index | |
| Post ID for posts, user ID for timelines | Celebrity accounts and viral posts | |
| Uber | Geographic cell | Dense city centers make hot cells; use smaller cells there |
| Payment system | Account or merchant ID | Transfers between accounts on different shards |
| File storage | User or namespace ID for metadata; content hash for blobs | Shared folders spanning users |
| Job scheduler | Hash of job ID, plus a time-bucketed index of due jobs | The "due now" bucket is always the hottest; split it across sub-buckets |
8. Mistakes to avoid
- Sharding too early. If the numbers fit one primary with replicas, say so; it is a strength, not a gap.
- No shard key. "Shard the database" without a key and a reason is not an answer.
- hash mod N with no plan for growth. Say how you add shards without moving most of the data.
- Timestamps or auto-increment IDs as range keys. Every new write lands on one shard.
- Ignoring the second query. The main query hits one shard; check what the others cost.
- Cross-shard transactions on the hot path. Redesign the key or use a saga.
- Forgetting replication. Shards without replicas turn one disk failure into lost data.
9. How to talk about it in the interview
- Justify sharding with the estimate that forces it.
- Name the key, the scheme and the query it serves in one sentence.
- Say what crosses shards and how you handle it.
- Mention hot keys and how you would add capacity before you are asked.
Fictional example
- Candidate
- At about 40,000 order writes a second at peak and 200 TB of history, one primary is not enough, so I will shard. Customers read their own orders, so the shard key is customer ID, hashed into 4,096 logical partitions spread over the nodes, each partition replicated three times.
- Interviewer
- What about a merchant who wants all orders for their store?
- Candidate
- That query would hit every shard. I would keep a second copy, keyed by merchant ID, fed asynchronously from the order stream, so merchant dashboards may lag by seconds. That is acceptable for reporting.
- Interviewer
- And a very large merchant?
- Candidate
- Their partition in the merchant copy becomes hot. With a directory on top of the hash, I can move them to dedicated partitions, and split their key by month if it is still too busy.
Practicing with Natively
Sharding answers fall apart on the second follow-up, so rehearse past the first. In a mock interview, Natively transcribes the conversation live and can suggest talking points for each question as it comes in; comparing them with what you said is a quick way to spot gaps such as hot partitions or how you would reshard. It can explain a screenshot you capture of a partitioning diagram or a problem statement. Afterwards the transcript and notes are kept for review, so you can see whether you named a shard key and defended it.
Questions people ask
How do you choose a shard key?
Pick a key with many distinct values that spreads load evenly, matches the main query so most requests touch one shard, and keeps data that changes together on the same shard. For chat messages, conversation ID usually fits better than sender or timestamp. Then check what your other queries cost under that key.
Why use consistent hashing instead of hash modulo N?
With hash modulo N, changing the number of shards moves most keys: going from 4 to 5 shards moves 80% of them. Consistent hashing moves only the share taken over by the new node, about 20% in that example, and virtual nodes keep the load even. Many systems get the same effect with a fixed number of logical partitions moved between nodes.
When should you shard a database?
Shard when writes exceed what one primary can take, when the data outgrows one machine or its backups take too long, or when the working set no longer fits in memory. Before that, a larger machine, read replicas, caching and archiving cold data are simpler. Sharding adds lasting complexity to queries, transactions and operations.
Where to go next
Practice with the same assistant you would use on a call: it listens, transcribes and suggests answers from your own resume and the job description.
Facts on this page were last checked on . Product details come from the Natively app itself; if something here is out of date, tell us at hello@heynatively.com.
