- remainder 0 → shard 0
- remainder 1 → shard 1
- remainder 2 → shard 2
- remainder 3 → shard 3
id % 4) to the user ID and go straight to the corresponding shard to fetch the data. There is no searching and no coordinator to ask.
Selecting the shard key is critical: it determines how data and load are distributed across shards, and changing it later is difficult and expensive. Consider this example layout produced by sharding on user ID:
country, every row on every shard must be inspected and many rows moved so that all rows for the same country end up together. For example, Chris (on shard 1) and Leo (on shard 2) are both from India — both rows would need to be relocated to a single shard. This can require a huge rebalancing operation and is error-prone.
So be absolutely sure about the shard key before sharding. Below are the five properties to evaluate when choosing a shard key.
-
High cardinality — many distinct values
The shard key should have many distinct values so data can be spread across many shards. Sharding bycountryprovides only ~200 values, which is insufficient if you need dozens of shards. User IDs usually have very high cardinality (each user typically has a unique ID), which allows even spreading. -
Even distribution (spread)
Values of the shard key should distribute load and storage evenly across shards. If most users join in the current year, sharding bysignup_yearwill overload the current-year shard while others remain underutilized. If you shard by user ID and generate IDs that map evenly (or hash them), new signups will be balanced across shards.

-
Matches access patterns (minimize scatter-gather)
Pick a shard key that aligns with your most common queries. If most requests fetch all data for a single user, sharding byuser_idensures the user’s rows are co-located on one shard. If you shardpostsbypost_id, a query to list all of Chris’s posts requires contacting every shard to find posts authored by Chris and then merging results — a pattern called scatter-gather that defeats the purpose of sharding. -
Immutability (the shard key should not change)
The shard key must remain stable for a row. Changing a shard key value requires moving that row to a different shard; if the operation fails mid-way, data can become inconsistent and the application may not know where to find the row. Immutable keys like internaluser_idare therefore safer shard keys than mutable fields likeusernameoremail. -
Co-location of related data
Applications often have related tables: users, posts, comments, likes. Ifusersis sharded byuser_idbutpostsis sharded bypost_id, a profile view requires fetching user data from one shard and posts from many shards. Sharding related tables by the same key (co-location) keeps related rows on the same shard and lets queries hit a single machine.

userId commonly satisfies all five properties above, it is often chosen as the shard key.
Choose a shard key carefully. Changing it later requires inspecting and moving data across every shard, which is expensive and error-prone.
id % 4) works for numeric keys. But shard keys can be non-numeric (for example username or email). How do we map arbitrary values to shard numbers and still spread data evenly? The answer is hashing.
Hashing approach
- Compute a deterministic numeric hash from any shard key value (string or number).
- Map the numeric hash to a shard by taking
hash % num_shards. - This supports numeric and non-numeric keys and tends to spread values evenly.

- consistent hashing (reduces the fraction of keys that move when shard count changes), or
- a mapping/proxy layer that maps keys to shard IDs (allowing you to reassign ranges or virtual nodes without moving all data at once).
Further reading and references
- Consistent hashing — Wikipedia
- MongoDB Sharding Concepts
- Designing Data-Intensive Applications — patterns for partitioning