Database Sharding Explained
Database sharding splits one large database into smaller, faster parts called shards. Each shard holds a subset of the data and operates independently. Sharding is the nuclear option : use it when vertical scaling, read replicas, and caching are not enough.
1. When to Shard
graph TD
Start["Single DB hitting limits"]
Step1{"Vertical scaling
enough?"}
Step2{"Read replicas
enough?"}
Step3{"Caching
enough?"}
Shard["Time to shard"]
Done["Stick with current setup"]
Start --> Step1
Step1 -->|"Yes"| Done
Step1 -->|"No, writes bottlenecked"| Step2
Step2 -->|"Yes"| Done
Step2 -->|"No, writes still bottlenecked"| Step3
Step3 -->|"Yes"| Done
Step3 -->|"No"| Shard
style Start fill:#FFF3CD,stroke:#FFC107
style Shard fill:#D97A2B,stroke:#B86418,color:#fff
style Done fill:#D4EDDA,stroke:#28A745- Write throughput exceeds what a single server can handle (tens of thousands of writes/sec)
- Read replicas help with read-heavy workloads, but writes are still bottlenecked on a single primary
- Vertical scaling (bigger hardware) is too expensive or has hit its ceiling
- Data size exceeds a single server's storage capacity
2. Choosing a Shard Key
The shard key determines which shard a record is stored on. This is the most critical decision : a bad shard key creates hot spots that negate the benefits of sharding.
graph TD
ShardKey["Shard Key Selection"]
UserID["User ID
All data for one user on same shard
Good for user-centric queries
Risk: hot spots for power users"]
Geo["Geographic Region
Data co-located with users
Reduces latency
Risk: uneven distribution"]
Timestamp["Timestamp
Time-series data naturally shards
Good for analytics
Risk: current time = hot shard"]
ShardKey --> UserID
ShardKey --> Geo
ShardKey --> Timestamp
style ShardKey fill:#D97A2B,stroke:#B86418,color:#fff
style UserID fill:#FAF6EE,stroke:#E8DFC8
style Geo fill:#FAF6EE,stroke:#E8DFC8
style Timestamp fill:#FAF6EE,stroke:#E8DFC83. Sharding Strategies
Hash-Based Sharding
Hash the shard key: shard = hash(key) % numShards. Even distribution, but adding/removing shards requires rehashing all keys.
graph LR
Key["user_id = 12345"]
Hash["hash(12345) = 78901234"]
Mod["78901234 % 4 = 2"]
Shard["Shard 2"]
Key --> Hash --> Mod --> Shard
style Key fill:#FAF6EE,stroke:#E8DFC8
style Hash fill:#D97A2B,stroke:#B86418,color:#fff
style Mod fill:#FAF6EE,stroke:#E8DFC8
style Shard fill:#D4EDDA,stroke:#28A745Range-Based Sharding
Assign key ranges to shards: Shard 0 gets keys 0-999, Shard 1 gets 1000-1999. Simple but can create hot spots if access patterns are skewed.
Consistent Hashing
Maps keys and shards onto a hash ring. When a shard is added/removed, only neighboring keys move. Minimizes data migration. Read our consistent hashing tutorial for details.
4. Architecture: Shard Router
graph LR
Client["Client"]
Router["Shard Router
(determines target shard)"]
S1["Shard 1
(users 0-999K)"]
S2["Shard 2
(users 1M-1.9M)"]
S3["Shard 3
(users 2M-2.9M)"]
S4["Shard 4
(users 3M+)"]
Client --> Router
Router --> S1
Router --> S2
Router --> S3
Router --> S4
style Client fill:#FAF6EE,stroke:#E8DFC8
style Router fill:#D97A2B,stroke:#B86418,color:#fff
style S1 fill:#FAF6EE,stroke:#E8DFC8
style S2 fill:#FAF6EE,stroke:#E8DFC8
style S3 fill:#FAF6EE,stroke:#E8DFC8
style S4 fill:#FAF6EE,stroke:#E8DFC85. Challenges of Sharding
Cross-Shard Queries
SQL JOINs across shards are expensive. You must query multiple shards and merge results in the application layer. Denormalize data to avoid joins.
Distributed Transactions
ACID transactions across shards require two-phase commit (2PC), which is slow and complex. Prefer eventual consistency where possible.
Rebalancing
When a new shard is added, existing data must be redistributed. This can cause downtime if not handled carefully. Use consistent hashing to minimize migration.
Global Unique IDs
Auto-increment IDs collide across shards. Use UUIDs, Snowflake IDs, or a centralized ID generator.
6. Common Interview Mistakes
- Sharding too early: Try vertical scaling, read replicas, and caching first. Sharding adds massive complexity.
- Poor shard key selection: An uneven shard key creates hot spots that negate the benefits of sharding.
- Ignoring cross-shard queries: Design your data model so most queries hit a single shard.
- Not planning for growth: Choose a shard key and strategy that supports 10x your current data size.
- Forgetting about monitoring: Shard health, query latency per shard, and data distribution must be tracked.
7. Summary
| Strategy | Pros | Cons |
|---|---|---|
| Hash-based | Even distribution | Adding shards rehashes all keys |
| Range-based | Simple, range queries efficient | Hot spots on current range |
| Consistent hashing | Minimal data migration | Complex implementation |
Put it into practice
Ready to practice?
Start a mock interview with AI interviewer Alex. Get instant hiring signal.
Start a Mock Interview →