> ## Documentation Index
> Fetch the complete documentation index at: https://notes.kodekloud.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Choosing the Shard Key

> Guide on selecting shard keys for database sharding, covering properties like cardinality, distribution, access patterns, immutability, co-location, and hashing strategies.

A common question when designing a sharded database is: when a request arrives for a user, how does the system know which shard holds that user's data?

One simple approach is to use the user's ID and compute a remainder. For example, take the user's numeric ID, divide by 4, and use the remainder to pick a shard:

* remainder 0 → shard 0
* remainder 1 → shard 1
* remainder 2 → shard 2
* remainder 3 → shard 3

In this approach the user ID is the column we used to decide which shard a user goes to. That column — whatever column we use to partition the data — is called the shard key. When a request for a user arrives, we apply the same function (for example `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:

```text theme={null}
SHARD 0
ID  USERNAME  COUNTRY  JOINED
12  wren      usa      2024
20  ivy       uk       2025
48  kim       japan    2026

SHARD 1
ID  USERNAME   COUNTRY  JOINED
41  chris_d    india    2026
13  martin     france   2025
25  omar       egypt    2026

SHARD 2
ID  USERNAME  COUNTRY  JOINED
18  leo       india    2026
26  alan      canada   2023
6   nina      brazil   2026

SHARD 3
ID  USERNAME  COUNTRY  JOINED
7   john      usa      2023
19  mia       spain    2026
31  raj       india    2025
```

If you later decide to change the shard key to `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.

1. High cardinality — many distinct values\
   The shard key should have many distinct values so data can be spread across many shards. Sharding by `country` provides 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.

2. 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 by `signup_year` will 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.

![A dark-themed diagram showing an app/server at the top fan-out to four database shards across the bottom labeled Shard 0 (2023), Shard 1 (2024), Shard 2 (2025), and Shard 3 (2026). The top menu highlights the "2 SPREADS EVENLY" option.](https://mintcdn.com/kodekloud-c4ac6d9a/U9fTv2NKZBAqmNMH/images/System-Design-Database-Sharding/Shard-Keys-and-Partitioning/Choosing-the-Shard-Key/app-fanout-4-shards-2spreads-evenly.jpg?fit=max\&auto=format\&n=U9fTv2NKZBAqmNMH\&q=85\&s=3570dd5e7330d52bee96e8481d12bfaa)

3. 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 by `user_id` ensures the user's rows are co-located on one shard. If you shard `posts` by `post_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.

4. 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 internal `user_id` are therefore safer shard keys than mutable fields like `username` or `email`.

5. Co-location of related data\
   Applications often have related tables: users, posts, comments, likes. If `users` is sharded by `user_id` but `posts` is sharded by `post_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.

![A diagram of a sharded database architecture showing an app routing user data (users, chirps, likes) to four database shards, with one shard highlighted. A phone UI labeled "Leo" is shown on the left as the client sending requests.](https://mintcdn.com/kodekloud-c4ac6d9a/U9fTv2NKZBAqmNMH/images/System-Design-Database-Sharding/Shard-Keys-and-Partitioning/Choosing-the-Shard-Key/sharded-database-app-routing-leo-phone.jpg?fit=max\&auto=format\&n=U9fTv2NKZBAqmNMH\&q=85\&s=942c9bae738d76aba9206f6ad4d6f830)

Because `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.

A practical problem remains: the simple remainder approach (for example `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.

![A diagram showing "Shard key = user ID" where an app routes user records to four database shards (0–3) by taking the user ID modulo 4. Example tables under each shard list user IDs and usernames, with ID 41 shown mapping to shard 1.](https://mintcdn.com/kodekloud-c4ac6d9a/U9fTv2NKZBAqmNMH/images/System-Design-Database-Sharding/Shard-Keys-and-Partitioning/Choosing-the-Shard-Key/shard-key-userid-mod4-sharding-diagram.jpg?fit=max\&auto=format\&n=U9fTv2NKZBAqmNMH\&q=85\&s=e92114487bf309ffcb3c151ad7676635)

Example (Python):

```python theme={null}
import hashlib

def shard_for_key(key, num_shards):
    # Compute a deterministic numeric hash for any key and map it to 0..num_shards-1
    h = hashlib.sha256(str(key).encode('utf-8')).hexdigest()
    return int(h, 16) % num_shards

# Examples
print(shard_for_key('user:41', 4))       # maps a string key deterministically to 0..3
print(shard_for_key('chris@example.com', 4))
print(shard_for_key(41, 4))              # integers work too (converted to string)
```

Hashing gives a consistent function that works for both numeric and non-numeric keys while helping to spread values across shards. One caveat: if you change the number of shards, the simple hash-then-modulo mapping remaps most keys and requires moving data. To reduce reshuffling when scaling, consider:

* 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).

Summary table: Key properties to evaluate when choosing a shard key

| Property | Why it matters | Example / notes |
| - | - | - |
| High cardinality | Enables spreading data across many shards | `user_id` vs `country` |
| Even distribution | Prevents hot shards and uneven load | Avoid `signup_year` if most signups are recent |
| Matches access patterns | Minimizes scatter-gather queries | Shard by `user_id` if most queries are per-user |
| Immutability | Avoids expensive in-place migrations | Prefer immutable values like internal IDs |
| Co-location | Keeps related rows together for joined queries | Shard `users`, `posts`, `likes` by same key |

Further reading and references

* [Consistent hashing — Wikipedia](https://en.wikipedia.org/wiki/Consistent_hashing)
* [MongoDB Sharding Concepts](https://www.mongodb.com/docs/manual/sharding/)
* [Designing Data-Intensive Applications — patterns for partitioning](https://dataintensive.net/)

If you need help evaluating candidate shard keys for a specific schema or workload, share your schema and common query patterns and I can help pick and justify a shard key.

> **[Watch Video](https://learn.kodekloud.com/user/courses/database-sharding/module/9c52f7ec-c4dc-4255-93b4-0467d4713ae6/lesson/c00c567a-76e5-4286-92ac-b0585c493f06)**


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.