🔥 0
0
Lesson 3 of 6 18 min +200 XP

Choosing the Right Shard Key

The shard key is the single most important decision in your sharding design. A bad shard key can make your sharded database perform worse than a single server. A good one can scale you to millions of users.

Warning: Changing Shard Keys is Hard

Once you choose a shard key and have data in production, changing it typically requires a complete data migration. Take time to get this right from the start.

What Makes a Good Shard Key?

A good shard key has four essential properties:

🎯
High Cardinality

Many unique values to spread across shards

⚖️
Even Distribution

Values are uniformly accessed

🔍
Query Alignment

Matches your query patterns

📌
Immutability

Value doesn't change over time

Property 1: High Cardinality

Cardinality is the number of unique values. Higher cardinality = more potential shards.
Low Cardinality (Bad):
  status: ["active", "inactive", "pending"]  // Only 3 values

High Cardinality (Good):
  user_id: [1, 2, 3, ... 100,000,000]  // Millions of values

Low Cardinality: status

Only 3 possible values means maximum 3 shards. 90% of users might be "active", creating a massive hotspot.

Shard "active" 90M users
Shard "inactive" 9M users
Shard "pending" 1M users

High Cardinality: user_id

100 million unique values. With hashing, users distribute evenly across any number of shards.

Shard 1 ~25M users
Shard 2 ~25M users
Shard 3 ~25M users
Shard 4 ~25M users

Property 2: Even Distribution

High cardinality isn't enough. The values must also be evenly accessed.

The Celebrity Problem

Twitter shards tweets by user_id. When Elon Musk tweets (300M followers), one shard handles millions of requests. High cardinality, but uneven access = hotspot.

Write Distribution vs Read Distribution

Consider both:

# User sign-ups (writes)
user_id: Even distribution ✓

# User activity (reads)
user_id: Uneven! Active users accessed 1000x more than dormant users

# Solution: Combine with hashing or accept some hotspots

Property 3: Query Alignment

Your shard key should match your most common queries. If queries don't include the shard key, you'll need to query all shards (scatter-gather).

# If shard key is user_id:

# GOOD: Query includes shard key - goes to one shard
SELECT * FROM orders WHERE user_id = 12345;

# BAD: Query doesn't include shard key - must query ALL shards
SELECT * FROM orders WHERE order_date = '2024-01-15';

Single-Shard Query

Query: WHERE user_id = 123

Router knows: user_id 123 is on Shard 2

Query 1 shard, get result

Scatter-Gather Query

Query: WHERE order_date = '2024-01-15'

Router doesn't know which shard has the data

Query ALL shards, merge results

Property 4: Immutability

The shard key value should never change. If it does, the record must move to a different shard.

# BAD: Mutable shard key
shard_key = user.country  # User moves from "US" to "UK"
# Now user's data needs to migrate from US shard to UK shard!

# GOOD: Immutable shard key
shard_key = user.id  # Never changes

Common Shard Key Patterns

Pattern 1: Entity ID

The most common pattern. Shard by the primary entity ID.

# E-commerce: Shard by user_id
orders = {
    "shard_key": "user_id",
    # All of a user's orders on same shard
}

# Messaging: Shard by conversation_id
messages = {
    "shard_key": "conversation_id",
    # All messages in a conversation together
}
Best For

Applications where queries are scoped to a single user/entity. "Show me my orders", "Show messages in this chat".

Pattern 2: Compound Keys

Combine multiple fields for better distribution and query flexibility.

# Multi-tenant SaaS
shard_key = (tenant_id, user_id)

# Benefits:
# 1. Queries with tenant_id go to subset of shards
# 2. Queries with tenant_id + user_id go to single shard
# 3. Large tenants spread across multiple shards
-- MongoDB compound shard key
sh.shardCollection("db.users", { tenant_id: 1, user_id: 1 })

-- Queries that work efficiently:
{ tenant_id: "acme" }                    -- Subset of shards
{ tenant_id: "acme", user_id: "u123" }   -- Single shard

Pattern 3: Hashed ID

Hash the ID to ensure even distribution (especially for sequential IDs).

# Auto-increment IDs are sequential
user_id = 1, 2, 3, 4, 5...

# Hash them for even distribution
shard_key = hash(user_id)

# Now sequential IDs distribute randomly across shards
hash(1) % 4 = 2
hash(2) % 4 = 0
hash(3) % 4 = 3
hash(4) % 4 = 1

Anti-Patterns: What to Avoid

Timestamp as Shard Key

All new writes go to the "current time" shard. Creates massive write hotspot.

shard_key = created_at // Bad

Low Cardinality Field

Limited values mean limited shards and uneven distribution.

shard_key = country // Only ~200 values

Monotonically Increasing

Sequential IDs with range sharding = all writes to last shard.

shard_key = auto_increment_id // With range sharding

Mutable Fields

If the shard key changes, data must migrate between shards.

shard_key = user.status // Can change

Real-World Case Study: Instagram

Instagram shards user data by user_id, but for the media table, they use a compound approach:

Instagram's Sharding

Instagram generates IDs that embed the shard information directly. Their IDs contain: timestamp (41 bits) + shard ID (13 bits) + sequence (10 bits). This way, the ID itself tells you which shard the data is on - no lookup needed.

# Instagram-style ID generation
def generate_id(shard_id):
    timestamp = current_time_ms() - EPOCH
    sequence = get_next_sequence()

    # 41 bits timestamp | 13 bits shard | 10 bits sequence
    id = (timestamp << 23) | (shard_id << 10) | sequence
    return id

# ID: 1387262464000 encodes shard 42
# You can extract shard_id directly from any ID

Decision Framework

Use this checklist when selecting a shard key:

Question What You Want
How many unique values? At least 10x your target shard count
Are writes evenly distributed? No single value should get >10% of writes
Do most queries include this key? 80%+ of queries should include the shard key
Does this value ever change? Never (or extremely rarely)
Will there be hotspots? Identify and plan for known hotspots

Key Takeaways

  • High cardinality - many unique values for proper distribution
  • Even distribution - both data and access patterns should be uniform
  • Query alignment - most queries should include the shard key
  • Immutable - shard key values should never change
  • Compound keys can provide better distribution and query flexibility

Next up: Rebalancing - What happens when you need to add or remove shards.

🧠 Quick Quiz

Test your understanding of this lesson.

1

What is the most important criterion for a good shard key?

2

Why is using an auto-incrementing ID as a shard key problematic?

3

What is a compound shard key?

Sharding Strategies