Guide · System design
Sharding Strategies: Range, Hash, Directory and Hot Keys
28 min readUpdated By Saket Bhatnagar
Researched and drafted with AI, reviewed and edited by Saket Bhatnagar.
In short
- Sharding strategies are the rules that decide which server, called a shard, holds each row once a database is split across many servers. The three main ones are range, hash and directory.
- Range sharding gives each shard one stretch of the shard key, the column that decides where a row goes. Nearby keys stay together, but keys that only go up, like new user ids, all land on the last shard.
- Hash sharding runs each key through a hash function, a formula that turns it into a scrambled number, so rows spread evenly. The price: a range query, one that asks for a stretch of keys like one week of charts, usually has to ask every shard.
- Directory sharding keeps a lookup table from key to shard. It is the most flexible, but the table must be fast and always up. No strategy can split one hot key, a key far busier than the rest.
- Beginners can stop after the comparison table in the middle. Engineers then get tested numbers: picking a server by the hash's remainder moved 80% of ids from 8 to 10 servers, against 19.5% with 256 fixed buckets. They also get the race that miscounts a hot counter split into parts.
What goes wrong when one database server cannot keep up?
One server has one disk, one CPU and one memory budget, and a growing app outgrows all three. A bigger machine buys time, but machines only get so big. Sharding strategies decide how you split the data across several servers instead, and each one breaks in its own way.
Picture a common setup. A music streaming app in Mumbai saves a play event every time someone plays a song. About 60 lakh (6 million) listeners have accounts, and most play songs every day. The setup is made up, but the problem is real.
Those play events feed three things: each listener's history, the play count on every song and the weekly charts. All of it lives on one big database server. The team has already moved to a bigger machine twice.
Now the plays table holds about 3 billion rows and the disk is 85% full. At the 9 pm peak, the server takes 15,000 writes a second and starts to lag. These numbers are made up but realistic.
This guide follows the team through three tries. The first plan breaks on new users, the second breaks when servers are added, and then one hit song breaks everything. Each failure teaches one strategy.
What is the difference between partitioning and sharding?
Partitioning means splitting one big set of data into smaller pieces, called partitions. Sharding means putting those pieces on different servers, so each server stores and serves only its share.
Many databases can partition a table inside one server. PostgreSQL, for example, can keep one partition per month of play events. Dropping a whole month's partition is far faster than deleting its rows one by one.
But one server's disk and CPU still carry everything. Sharding spreads that load across machines, and each machine with its piece is called a shard.
Splitting by columns, or moving whole tables to different servers, is often called vertical partitioning. The app could keep song details on one server and play events on another. That helps for a while, but the plays table alone is still too big.
Splitting the rows of one table across servers is called horizontal partitioning, and it is what this guide covers.
Two more words come up again and again. The shard key is the column used to decide where a row goes, such as user_id. The router is the code that reads the shard key and sends each query to the right shard.
What are the main sharding strategies?
The main sharding strategies are range sharding, hash sharding and directory sharding. They differ in one thing: how the router turns a shard key into a shard number.
- Range sharding: each shard owns one continuous stretch of keys, such as user ids 1 to 15 lakh.
- Hash sharding: the router runs the key through a hash function (a formula that turns any input into a scrambled number) and picks the shard from that number.
- Directory sharding: a lookup table records which shard holds each key, or each group of keys, and the router reads that table first.
Picture a big wholesale cloth market with five lanes of shops. The market committee must decide which shop sits in which lane, so buyers know where to walk. That choice is a sharding strategy, and the lanes are your shards.
The committee could give lanes by shop name: names from A to E in lane 1, F to J in lane 2, and so on. That is range sharding. It could use the last digit of each shop's licence number instead, which scatters shops evenly. That works like hash sharding.
Or it could let shops sit anywhere and put up a big board at the gate that lists every shop's lane. That is directory sharding. Keep this market in mind, because each strategy has a market version of its main weakness.
Here is how the market maps onto a database:
- A shop is one row, and its name or licence number is the shard key.
- A lane is one shard.
- The committee's rule for lanes is the sharding strategy.
- The board at the gate is the directory.
- A buyer looking for a shop is a query, and the gatekeeper who points the way is the router.
Where the picture breaks: a real hash scrambles any key, even a name. The last digit only scatters shops because licence numbers are already spread out. And real shards keep copies of each row on replicas, which no market lane does.
How does range sharding work?
Range sharding splits the keys into continuous ranges and gives each range to one shard. The router keeps a short list of boundaries and checks which range a key falls into.
The team's first plan shards play events by user_id into four ranges. Users up to 15 lakh go to shard 1, the next 15 lakh go to shard 2, and so on. A listener's whole history sits on one shard, so the history screen needs just one query.
Range sharding of play events by user_id
Drag to exploreEach shard owns one continuous stretch of user ids. Notice that every new id lands on shard 4, however idle the other three are.
Diagram connections:
- Music app to Shard router
- Shard router to Shard 1: 1 to 15 lakh (Old users)
- Shard router to Shard 2: 15 to 30 lakh
- Shard router to Shard 3: 30 to 45 lakh
- Shard router to Shard 4: 45 lakh and up (All new users)
- Music app: Sends play events with a user_id
- Shard router: Checks which range the user_id falls in
- Shard 1: 1 to 15 lakh: Older listeners, steady load
- Shard 2: 15 to 30 lakh: Steady load
- Shard 3: 30 to 45 lakh: Steady load
- Shard 4: 45 lakh and up: Gets every new sign-up and most writes
Here is the trouble. User ids grow by one with every sign-up, so they are monotonically increasing: they only ever go up. In this app, new users are the most active listeners, and all of them land on shard 4.
MongoDB, a widely used document database, documents the same trap. Its shard key guide says that if the key always increases, every new insert goes to the chunk at the top of the key range. A chunk is MongoDB's word for one range of keys.
The shard holding that top chunk becomes the bottleneck for writes. Timestamps cause the same problem, because they also only go up.
Range sharding still has a real strength. Rows with close keys sit together, so a query over a stretch of keys touches only one or two shards. If the team shards its charts table by week, the query for last week's chart reads from one shard.
The market shows both sides. Lanes by shop name make it easy to visit every shop starting with M in one short walk. But if most new shops this year have names starting with S, lane 4 overflows while the other lanes stay quiet.
How does hash sharding work?
Hash sharding runs the shard key through a hash function and uses the result to pick a shard. Keys that look alike get very different hash values, so rows spread evenly across shards.
The team's second plan hashes user_id across eight shards. User 6000001 and user 6000002 now land on different shards, so new sign-ups spread over all of them. Here is the routing code; it runs on any Python 3 with no extra packages.
import hashlib
NUM_SHARDS = 8
def shard_for(user_id: str) -> int:
digest = hashlib.md5(user_id.encode()).digest()
number = int.from_bytes(digest[:8], "big")
return number % NUM_SHARDS
print(shard_for("6000001"), shard_for("6000002"))Run it and it prints 4 2: user 6000001 goes to shard 4 and user 6000002 goes to shard 2. Two lines matter. The md5 line turns the id into a fixed, scrambled number.
Here md5 is fine because you need spread, not security. Do not use Python's built-in hash() for this. For strings it is salted with a new random value each time Python starts. Unless PYTHONHASHSEED is set, the same id gets a different number in every run.
The line with % NUM_SHARDS keeps only the remainder after dividing by 8. So every id maps to a shard numbered 0 to 7, and the same id always maps to the same shard.
The cost shows up in range queries. MongoDB's hashed sharding page says that after hashing, documents with close key values are unlikely to share a chunk or shard. So a range query is likely to become a broadcast, sent to every shard.
A query for one exact key still goes to a single shard. For play events that is fine, because the app almost always asks for one user's history. For the charts table, hashing by date would turn every weekly chart into a query to all eight shards.
A bigger cost comes when you add servers. Change NUM_SHARDS from 8 to 10 and the remainder changes for about 80% of ids, so about 80% of rows must move. A fair share would be 20%, the part the two new servers should take over.
Consistent hashing places servers and keys on a ring, and each key belongs to the next server along the ring. A new server takes over only the keys just before its own spot, so on average only about that fair 20% moves.
That second idea is common. The team hashes into 256 logical shards (small fixed buckets) and maps them onto 8 servers. Adding a server means moving some whole buckets, never rehashing every row. Notice that the map from bucket to server is a small directory.
What is directory-based sharding?
Directory-based sharding keeps a lookup table that records which shard holds each key or group of keys. The router reads the directory first, then sends the query to the shard it names.
This is the board at the gate of the cloth market. Shops can sit in any lane. When a shop moves, the committee changes one line on the board, and no other shop has to move.
The app uses a directory for record labels. Each label manages its catalogue (its list of songs and albums) through a label portal. One large label has more songs than the next 50 labels combined, so the team gives it a shard of its own while small labels share shards.
A hash formula cannot place one label by hand. Range boundaries could, but they would need re-carving as labels grow. A directory makes it a one-line change. In the diagram, follow the numbered arrows from the router, and notice where the directory's copy lives.
Directory sharding for label catalogues
Drag to exploreThe router asks its cached copy of the directory which shard holds a label, then queries only that shard. Notice the directory pushes changes to the cache, so a stale cache is the main risk.
Diagram connections:
- Label portal to Shard router
- Shard router to Directory cache (1. Which shard?)
- Shard directory to Directory cache (Pushes changes)
- Shard router to Shard 1 (2. Query)
- Shard router to Shard 2 (2. Query)
- Shard router to Shard 3 (2. Query)
- Label portal: Asks for one label's songs
- Shard router: Never guesses, always checks the directory
- Directory cache: Copy kept in each router's memory
- Shard directory: Rows like label_17 is on shard 3
- Shard 1: The one big label, alone
- Shard 2: Many small labels
- Shard 3: Many small labels
Real systems use the same lookup idea for routing. Vitess, a sharding system for MySQL, has lookup vindexes. Its documentation describes one as a MySQL lookup table that maps a column value to keyspace IDs.
A keyspace ID is the value Vitess computes to place a row. Each shard covers a range of keyspace IDs, so a row's keyspace ID decides which shard holds it. The lookup table does not move rows. It tells the router where rows with that column value already live, so queries on that column reach the right shard.
The flexibility has a price. Every query needs the directory, so it must be fast and must never be down. Routers keep a cached copy, and the directory table itself is replicated like any other important table.
Moving a label is where a directory earns its keep, and where it needs care. Here is how the team moves a growing label from shard 2 to a new shard 4 without losing a write.
Copy the rows
Copy all of the label's rows from shard 2 to shard 4, while the portal keeps working on shard 2.
Catch up on changes
Replay the edits made on shard 2 during the copy, until shard 4 is only seconds behind.
Pause writes briefly
Block writes for that one label for a moment, and apply the last few changes.
Flip the directory
Change the label's row in the directory to shard 4, and push the change to every router's cache.
Clean up later
Resume writes, watch for errors for a day, then delete the old rows from shard 2.
How do you choose a good shard key?
A good shard key spreads both data and traffic evenly, and matches how your app reads data. Get the key right first, because a poor key hurts every strategy.
- Many distinct values. The app has tens of lakhs of user_id values. MongoDB's own example is a continent column: seven values means at most seven chunks, so more than seven shards never help.
- Each value is rare. If one value appears in a large share of rows, the shard holding it grows too big, and that range cannot be split further.
- Values that do not only rise. Under range sharding, a key that keeps increasing sends every new write to one place.
- Your most common query uses it. The history screen asks by user_id, so user_id keeps that query on one shard.
The first three match MongoDB's advice for shard keys: high cardinality (many distinct values), low frequency (no value is very common) and no monotonic change. The fourth comes from your own query logs.
Lanes by fabric fail the first test. There are only a few fabrics, so the market can never use more lanes than it has fabrics. Worse, demand follows the season. In wedding season the silk lane is mobbed, while the cotton lane sits nearly empty.
Changing a shard key later is painful, because every row may need to move. MongoDB 5.0 and later can reshard a collection (its word for a table) to a new key, but it still copies all the data, so choose early.
What is a hot key, and how do you fix a hot partition?
A hot key is a single key that gets far more traffic than the rest, and a hot partition is the shard that holds it. You fix it by spreading or reducing the work for that one key, because no sharding strategy can split a single key.
On a Friday, a big film song is released at 6 pm. Within an hour, about one in four plays on the app is that song. Each play adds one to the song's play counter, a single row on shard 2.
At 7:10 pm the on-call engineer is paged. Shard 2 sits at 98% CPU, while the other seven shards are near 25% (numbers made up). Writes to the counter queue up, and plays of other songs stored on shard 2 slow down too.
Notice what went wrong. Hashing spread the songs evenly, but it spreads keys, not traffic. All the work for one song still has one address.
Managed databases hit the same wall. Amazon DynamoDB's guide says each partition is designed for at most 3,000 read units and 1,000 write units a second, as of October 2026. One write unit is one write a second of an item up to 1 KB.
Above that, DynamoDB throttles, which means rejecting the extra requests. Its adaptive capacity can move a very busy item onto a partition of its own, but that item still gets at most the partition maximum.
The team's fix for the counter is to split it. Follow the arrows in the diagram from a play event to the number on the song page.
Splitting the hot song's play counter
Drag to exploreWrites for one hot song spread over 16 counter parts. Notice the song page never reads the parts itself: a sum job adds them up and the page reads one cached total.
Diagram connections:
- Play events to Counter writer
- Hot-key detector to Counter writer (Marks the song as hot)
- Counter writer to 16 counter parts (Add 1 to one part)
- 16 counter parts to Sum job (Read all parts)
- Sum job to Total plays cache (Save the total)
- Song page to Total plays cache (Read the count)
- Play events: About one in four is the hit song
- Hot-key detector: Counts requests per key every minute
- Counter writer: Adds a random part number for hot songs
- 16 counter parts: Spread over several shards
- Sum job: Adds up all parts every few seconds
- Total plays cache: One number per song
- Song page: Shows the play count
Here is the counter code. The db object stands in for any key-value store (a database that saves values under keys) with get and increment.
import random
HOT_SONGS = {"song_7781"} # filled by the hot-key detector
PARTS = 16
def counter_key(song_id):
if song_id in HOT_SONGS:
return f"plays:{song_id}#{random.randrange(PARTS)}"
return f"plays:{song_id}"
def record_play(db, song_id):
db.increment(counter_key(song_id))
def total_plays(db, song_id):
keys = [f"plays:{song_id}"]
if song_id in HOT_SONGS:
keys += [f"plays:{song_id}#{n}" for n in range(PARTS)]
return sum(db.get(k) or 0 for k in keys)The counter_key function adds a random part number from 0 to 15, but only for songs in HOT_SONGS. The total_plays function also reads the original key, because plays from before the song turned hot still sit there.
Under hash sharding the 16 part keys spread over the shards, but not one per shard. With eight shards, the team's check put the parts on 6 shards, with up to 4 parts on one. More parts give a smoother spread, but every total costs one more read.
DynamoDB's guide calls this trick write sharding. Its example adds a random suffix from 1 to 200 to a busy date key. It is honest about the cost: to read a whole day back, you query all 200 suffixes and merge the results.
That cost is why only hot songs get split; a quiet song still costs one read. Folding a cooled-down song back into one key is harder than it looks, and an engineer section below shows why.
Other ways to cool a hot key
- Cache the reads. Show the play count from a cache that refreshes every few seconds. Nobody needs the exact count to the second.
- Batch the writes. Each app server adds up plays in memory and writes one +500 every few seconds, instead of 500 separate +1 writes. A server crash loses those few seconds of plays.
- Give the key its own home. With a directory, the hottest songs can move to a shard with nothing else on it, though that shard still has one machine's limit.
- Spot it early. Count requests per key, and alert when one key passes a set share of a shard's traffic.
Back in the market, nobody can split the busiest bridal silk shop in two during wedding season. But the shop can send helpers to take orders at the lane entrance, hand out printed price lists, and bill everyone together at closing time. That is splitting, caching and batching.
Which sharding strategy should you use?
Use hash sharding when you mostly look up single keys, range sharding when you often read ranges of keys, and directory sharding when placement must be flexible. Real systems often combine them: Vitess places rows by ranges of keyspace IDs and routes some queries through lookup tables.
| Range | Hash | Directory | |
|---|---|---|---|
| How the shard is picked | The range the key falls in | The hash of the key | A lookup in a table |
| Spread of data | Can be uneven | Even for most keys | Whatever you assign |
| Range queries | Fast, one or few shards | Slow, usually every shard | Depends on how keys are grouped |
| Keys that only go up | All new writes hit one shard | Spread evenly | Spread if you assign them well |
| Adding a shard | Split a range and move it | About 80% of keys move with plain mod N, 8 to 10 | Change some entries, move those rows |
| Extra part to run | A small range map | None beyond the formula | A fast, replicated directory |
| Use in the music app | Weekly charts by date | Play events by user_id | Label catalogues |
The app ends up using all three. Play events hash on user_id. Weekly charts use date ranges, because the chart query reads one week at a time. Label catalogues use a directory, so the biggest label gets a shard of its own.
If you are unsure, follow the questions in this diagram. Every path ends at the same box.
Picking a sharding strategy
Drag to exploreYour most common query picks the strategy. Hot keys need a plan whichever one you choose.
Diagram connections:
- Your most common query to Reads ranges of keys?
- Reads ranges of keys? to Range sharding (Yes)
- Reads ranges of keys? to Need to place keys by hand? (No)
- Need to place keys by hand? to Directory sharding (Yes)
- Need to place keys by hand? to Hash sharding (No)
- Range sharding to Plan for hot keys
- Directory sharding to Plan for hot keys
- Hash sharding to Plan for hot keys
- Your most common query: Found in your query logs
- Reads ranges of keys?: Like one week of charts
- Need to place keys by hand?: Like one huge label on its own
- Range sharding: Watch keys that only go up
- Directory sharding: Keep the directory cached and replicated
- Hash sharding: Plan how you will add shards
- Plan for hot keys: Split, cache or batch the busiest keys
How many rows move when you add a shard?
With plain hash mod N, most rows move. With logical shards or consistent hashing, only about the new servers' fair share moves. The team measured all of them on 10 lakh user ids going from 8 to 10 servers.
| Approach | Ids that move | The catch |
|---|---|---|
| Plain hash mod N | 80.0% | Almost every row is copied between servers |
| 256 logical shards | 19.5% (50 of 256 buckets) | Pick the bucket count up front; 10 servers get 25 or 26 buckets each |
| Consistent hashing, 1 point per server | 16.5% | Very uneven: the busiest server held 20.3% of ids, the quietest 0.4% |
| Consistent hashing, 100 points per server | 21.2% | Each server held 8.8% to 11.2%; every lookup searches the ring |
Two results deserve a note. Doubling from 8 to 16 shards moves half the rows under mod N, which is exactly the new servers' fair share. So if you are stuck with mod N, grow by doubling. And a ring with one point per server is badly uneven.
So give each server many points on the ring, often called virtual nodes. With 100 points per server, the spread was close to even and the move share stayed near 20%.
Check it yourself
Run this on any Python 3; it needs no packages. It counts how many of 1 lakh ids change shard when the shard count changes.
import hashlib
def h(key: str) -> int:
return int.from_bytes(hashlib.md5(key.encode()).digest()[:8], "big")
ids = [str(n) for n in range(1, 100_001)]
for old, new in [(8, 10), (8, 16)]:
moved = sum(1 for k in ids if h(k) % old != h(k) % new)
print(f"{old} to {new} shards: {moved / len(ids):.1%} of ids move")It prints two lines: 8 to 10 shards: 80.2% of ids move, then 8 to 16 shards: 49.9% of ids move. Your numbers should match exactly, because md5 gives the same result on every machine.
What breaks when you split a hot key and later fold it back?
Two things break. Readers that do not yet know a key is split miss its parts, and folding parts back with separate writes miscounts in between. Both come from one HOT_SONGS set driving writes and reads at once.
Take a song with 1,000 plays on the original key and 800 spread over 16 parts of 50 each. A fold job adds part 0's 50 plays to the original key, then deletes part 0. A reader between those two writes sees 1,850, not 1,800.
Removing the song from HOT_SONGS before the fold ends is worse. Readers then skip the 15 unfolded parts and show 1,050. The same gap opens at the start, if one server writes to parts before every reader knows they exist.
The fix is to keep two lists, one for readers and one for writers, and change them in a fixed order. The fold step also needs a snapshot read.
Readers learn first
Add the song to the readers' list and wait until every server has the new list.
Then writers split
Only then add the song to the writers' list, so writes start going to the parts.
Stop writing parts first
To cool the song down, remove it from the writers' list and wait until every server has the change. Keep reading the parts.
Fold in one step
Move each part into the original key with one transaction that adds and deletes together. The sum job must also read all 17 keys in one snapshot, a view of every key at one instant. Otherwise it can still count a part twice or miss one. If your store cannot do both, keep reading the parts and do not fold.
Readers forget last
Remove the song from the readers' list only when every part is gone.
How does MongoDB rebalance ranges and reshard a collection?
MongoDB moves data on its own, but only past a threshold, and changing a key means copying the collection. These numbers come from the MongoDB 9.0 manual as of October 2026, so check them against your version.
- The balancer is a background process. It moves data only when the shard with the most data for a collection holds at least three times the range size more than the shard with the least.
- The range size is the target size of one range, 128 MB by default, so the gap must reach 384 MB. Each shard takes part in one migration at a time, so n shards run at most n/2 migrations at once, rounded down.
- For a key that keeps rising, the top chunk is placed on a different shard when it splits. That moves the hot spot around, but at any moment one shard still takes all new inserts. In 9.0, chunks split only when they must be migrated, so this relief comes slowly.
- The reshardCollection command, available from MongoDB 5.0, blocks writes to the collection for up to two seconds, and your app must tolerate that. Every resharding takes at least 5 minutes.
- Each receiving shard needs free space of about twice the collection plus its indexes, divided by the number of shards. From MongoDB 8.0 you can reshard on the same key to spread data onto new shards.
How do you explain sharding strategies in a system design interview?
Explain sharding as a chain of choices: why you must shard, which key, which strategy, and how you handle growth and hot keys. Use rough numbers to show that each step is needed.
Show the need
Estimate data size and peak writes, and say why one server cannot hold them. Mention that replicas copy data but do not split it.
Name the main query
Say which query must be fastest, such as one user's listening history. That query decides the shard key.
Pick the key and the strategy
Choose a key with many values and even traffic. Pick range, hash or directory, and say what gets slower.
Plan for growth
Explain how you add shards without moving everything. Plain mod N moves about 80% of rows going from 8 to 10; logical shards move about the fair 20%.
Handle hot keys
Raise the hit song case yourself. Explain split counters, cached reads and batched writes for that one key, and that readers must learn about a split first.
Cover cross-shard queries
Say how you answer queries that need every shard, such as a global top 10. Use scatter-gather (ask every shard, then merge) or a separate summary table.
Questions people ask
- Is sharding the same as partitioning?
- Not quite. Partitioning means splitting data into pieces, which can all stay on one server. Sharding means placing those pieces on different servers, so each server stores and serves only its share. People often use the words loosely, so check which one someone means.
- Is hash sharding better than range sharding?
- Neither is better everywhere. Hash sharding spreads keys evenly and copes with keys that only go up, but range queries usually ask every shard. Range sharding keeps range queries fast, but can pile writes onto one shard. Pick based on your most common query.
- When should you shard a database?
- Shard when one server cannot hold your data or keep up with your writes, even after a bigger machine, better indexes, caching and read replicas. Sharding adds real work: routing, cross-shard queries and moving data. Many apps never need it, so measure first.
- What happens to joins and transactions after sharding?
- They get harder when the rows live on different shards. A join across shards means fetching from several servers and combining the results in code. A transaction across shards needs extra coordination between servers. A good shard key keeps related rows together, so most joins and transactions stay on one shard.
- Does consistent hashing stop data from moving?
- No, it only limits how much moves. In the team's test, adding 2 servers to 8 moved about 21% of ids with 100 ring points per server, against 80% with plain mod N. The moved rows still have to be copied while the app keeps serving traffic.
- Can a database fix hot keys for me?
- Only partly. DynamoDB's adaptive capacity can move a very busy item onto a partition of its own. Its documentation says that item still gets at most the partition maximum of 1,000 write units a second, as of October 2026. So you still need split keys, caching or batching for anything busier.
- What is resharding?
- Resharding means changing how data is split, such as adding shards or choosing a new shard key. It copies rows between servers while the app keeps running, so it is slow and needs care. In MongoDB 9.0 it takes at least 5 minutes and needs spare disk on every receiving shard.
Sources and further reading
- MongoDB Manual: Choose a Shard Key (cardinality, frequency, monotonic keys, reshardCollection from 5.0)
- MongoDB Manual: Ranged Sharding (contiguous ranges, close keys share a chunk)
- MongoDB Manual: Hashed Sharding (range queries become broadcasts)
- MongoDB Manual: Sharded Cluster Balancer (384 MB threshold, one migration per shard)
- MongoDB Manual: Reshard a Collection (two-second write block, 5-minute minimum, disk space)
- Vitess documentation: Vindexes, including lookup vindexes and keyspace IDs
- Amazon DynamoDB Developer Guide: Designing partition keys (per-partition limits, write units)
- Amazon DynamoDB Developer Guide: Using write sharding to distribute workloads evenly
- Amazon DynamoDB Developer Guide: Burst and adaptive capacity
- PostgreSQL 18 documentation: Table Partitioning