Skill — Database Sharding (Advanced)
When this skill activates
Any task involving horizontal database partitioning across multiple nodes,
shard key selection, hotspot mitigation, resharding without downtime,
cross-shard query strategies, or geographic data distribution.
Mandatory actions when this skill is active
Before writing any code
- Confirm sharding is necessary (vertical scaling exhausted? read replicas insufficient?).
- Select shard key using the three criteria: high cardinality + even distribution + query alignment.
- Plan cross-shard query strategy for necessary joins/aggregations.
- Design resharding approach (will need it eventually — plan now).
During implementation
- Implement shard routing layer (application-level or proxy).
- Use consistent hashing with virtual nodes for even distribution.
- Denormalize data that would require frequent cross-shard joins.
- Pre-compute aggregations that span shards.
- Handle shard-local sequences (no global auto-increment).
- Implement request routing that is transparent to application code.
After implementation
- Verify even distribution across shards (no hotspots).
- Test cross-shard queries perform within acceptable latency.
- Validate resharding procedure in staging (dual-write → migrate → verify → cut).
- Monitor per-shard metrics (query latency, storage, connections).
- Load test at 2x expected traffic to validate shard capacity.
Shard Key Selection
Three Criteria (All Must Be Met)
- High cardinality: Many distinct values (user_id: good, country: bad).
- Even distribution: Values spread evenly across shards (random UUID: good, sequential ID: bad for hash).
- Query alignment: Most queries include the shard key (tenant_id if multi-tenant).
Common Shard Keys
| Application Type |
Good Shard Key |
Why |
| Multi-tenant SaaS |
tenant_id |
All tenant data co-located |
| Social media |
user_id |
Profile + posts together |
| E-commerce |
customer_id |
Orders, cart, history together |
| IoT |
device_id |
Time-series per device |
| Gaming |
player_id |
Player state co-located |
Anti-Pattern Shard Keys
- Timestamp: Creates hot shard (all writes to "current" shard).
- Sequential ID: Skews to latest shard.
- Country/region: Uneven (US shard overloaded, small countries under-utilized).
- Status field: Low cardinality, uneven distribution.
Hotspot Mitigation
Techniques
- Hash distribution: Hash shard key before routing (spreads sequential keys).
- Virtual shards: Map to many virtual shards, assign groups to physical nodes.
- Composite keys: Combine shard key with secondary attribute (user_id + date_bucket).
- Time-based rotation: For time-series, rotate shard assignment periodically.
- Write-behind aggregation: Buffer hot-key writes, flush periodically.
Detecting Hotspots
- Monitor per-shard write rate (>2x average = hotspot).
- Monitor per-shard storage growth (uneven = distribution problem).
- Monitor per-shard query latency (one slow = overloaded).
Resharding Without Downtime
The Double-Write Pattern
Phase 1: Dual-Write
- Write to both old shard AND new shard.
- Read from old shard.
Phase 2: Backfill
- Copy historical data from old shard to new shard.
- Continue dual-writing.
Phase 3: Verify
- Compare old and new shard data (row counts, checksums).
- Fix any discrepancies.
Phase 4: Cutover
- Switch reads to new shard.
- Continue dual-writing briefly (safety net).
Phase 5: Cleanup
- Stop writing to old shard.
- Archive/delete old shard data.
Online Schema Change Tools
- gh-ost (GitHub): Trigger-free, replication-based.
- pt-online-schema-change (Percona): Trigger-based.
- Spirit: For MySQL resharding specifically.
Rules
- Never do big-bang migration (all-at-once = risky).
- Always have rollback plan at every phase.
- Verify data integrity between phases (checksums).
- Run in staging first with production-like data volume.
Cross-Shard Queries
The Problem
Once data is sharded, joins across shards are expensive (scatter-gather).
Strategies
| Strategy |
When to Use |
Trade-off |
| Denormalization |
Frequent joins |
Storage cost, write complexity |
| Pre-computed aggregations |
Analytics, dashboards |
Staleness, compute cost |
| Scatter-gather |
Rare queries |
Latency, complexity |
| Global tables (replicated) |
Small reference data |
Replication lag |
| Application-level joins |
Low-volume cross-shard |
Code complexity |
Denormalization Patterns
- Store user name alongside every order (avoid cross-shard user lookup).
- Embed category info in product documents.
- Maintain per-shard aggregation counters (updated async).
When Scatter-Gather Is Acceptable
- Admin queries (not user-facing, latency tolerant).
- Batch jobs (run off-peak).
- Infrequent search queries (use dedicated search index instead).
Consistent Hashing
How It Works
- Hash ring with positions 0 to 2^32.
- Each physical node gets multiple virtual nodes (tokens) on the ring.
- Data routes to first node clockwise from its hash position.
- Adding/removing node only affects adjacent range.
Virtual Nodes
- Each physical node owns 100-256 virtual nodes.
- More virtual nodes = more even distribution.
- Adding a physical node: assign new virtual nodes, migrate only affected ranges.
- Removing: redistribute its virtual nodes' ranges to neighbors.
Benefits Over Simple Modulo
| Aspect |
Modulo (hash % N) |
Consistent Hashing |
| Add node |
~100% data moves |
~1/N data moves |
| Remove node |
~100% data moves |
~1/N data moves |
| Distribution |
Depends on hash |
Even with virtual nodes |
| Complexity |
Simple |
Moderate |
Geographic Sharding
Use Cases
- Data sovereignty (EU data stays in EU).
- Latency optimization (users read from nearest region).
- Regulatory compliance (GDPR, data residency laws).
Patterns
| Pattern |
Reads |
Writes |
Consistency |
| Write-local, read-local |
Fast |
Fast |
Eventual (per-region) |
| Write-primary, read-any |
Fast |
Slower (cross-region) |
Strong for writes |
| Multi-writer |
Fast |
Fast |
Conflict resolution needed |
Conflict Resolution (Multi-Writer)
- Last-write-wins (simple, data loss possible).
- CRDTs (conflict-free, limited data types).
- Application-level merge (complex, most flexible).
- Operational transforms (collaborative editing).
Shard Routing
Routing Approaches
- Application-level: App knows shard map, routes directly.
- Proxy layer: Middleware (Vitess, ProxySQL) routes transparently.
- Client library: SDK handles routing, app unaware.
Shard Map
{
"shards": [
{"id": 0, "range": "0000-3FFF", "host": "db-shard-0.internal"},
{"id": 1, "range": "4000-7FFF", "host": "db-shard-1.internal"},
{"id": 2, "range": "8000-BFFF", "host": "db-shard-2.internal"},
{"id": 3, "range": "C000-FFFF", "host": "db-shard-3.internal"}
]
}
Self-check
1---2name: database-sharding-advanced3description: Skill — Database Sharding (Advanced)4---56# Skill — Database Sharding (Advanced)78## When this skill activates9Any task involving horizontal database partitioning across multiple nodes,10shard key selection, hotspot mitigation, resharding without downtime,11cross-shard query strategies, or geographic data distribution.1213## Mandatory actions when this skill is active1415### Before writing any code161. Confirm sharding is necessary (vertical scaling exhausted? read replicas insufficient?).172. Select shard key using the three criteria: high cardinality + even distribution + query alignment.183. Plan cross-shard query strategy for necessary joins/aggregations.194. Design resharding approach (will need it eventually — plan now).2021### During implementation22- Implement shard routing layer (application-level or proxy).23- Use consistent hashing with virtual nodes for even distribution.24- Denormalize data that would require frequent cross-shard joins.25- Pre-compute aggregations that span shards.26- Handle shard-local sequences (no global auto-increment).27- Implement request routing that is transparent to application code.2829### After implementation30- Verify even distribution across shards (no hotspots).31- Test cross-shard queries perform within acceptable latency.32- Validate resharding procedure in staging (dual-write → migrate → verify → cut).33- Monitor per-shard metrics (query latency, storage, connections).34- Load test at 2x expected traffic to validate shard capacity.3536## Shard Key Selection3738### Three Criteria (All Must Be Met)391. **High cardinality**: Many distinct values (user_id: good, country: bad).402. **Even distribution**: Values spread evenly across shards (random UUID: good, sequential ID: bad for hash).413. **Query alignment**: Most queries include the shard key (tenant_id if multi-tenant).4243### Common Shard Keys44| Application Type | Good Shard Key | Why |45|-----------------|---------------|-----|46| Multi-tenant SaaS | tenant_id | All tenant data co-located |47| Social media | user_id | Profile + posts together |48| E-commerce | customer_id | Orders, cart, history together |49| IoT | device_id | Time-series per device |50| Gaming | player_id | Player state co-located |5152### Anti-Pattern Shard Keys53- **Timestamp**: Creates hot shard (all writes to "current" shard).54- **Sequential ID**: Skews to latest shard.55- **Country/region**: Uneven (US shard overloaded, small countries under-utilized).56- **Status field**: Low cardinality, uneven distribution.5758## Hotspot Mitigation5960### Techniques611. **Hash distribution**: Hash shard key before routing (spreads sequential keys).622. **Virtual shards**: Map to many virtual shards, assign groups to physical nodes.633. **Composite keys**: Combine shard key with secondary attribute (user_id + date_bucket).644. **Time-based rotation**: For time-series, rotate shard assignment periodically.655. **Write-behind aggregation**: Buffer hot-key writes, flush periodically.6667### Detecting Hotspots68- Monitor per-shard write rate (>2x average = hotspot).69- Monitor per-shard storage growth (uneven = distribution problem).70- Monitor per-shard query latency (one slow = overloaded).7172## Resharding Without Downtime7374### The Double-Write Pattern75```76Phase 1: Dual-Write77 - Write to both old shard AND new shard.78 - Read from old shard.7980Phase 2: Backfill81 - Copy historical data from old shard to new shard.82 - Continue dual-writing.8384Phase 3: Verify85 - Compare old and new shard data (row counts, checksums).86 - Fix any discrepancies.8788Phase 4: Cutover89 - Switch reads to new shard.90 - Continue dual-writing briefly (safety net).9192Phase 5: Cleanup93 - Stop writing to old shard.94 - Archive/delete old shard data.95```9697### Online Schema Change Tools98- **gh-ost** (GitHub): Trigger-free, replication-based.99- **pt-online-schema-change** (Percona): Trigger-based.100- **Spirit**: For MySQL resharding specifically.101102### Rules103- Never do big-bang migration (all-at-once = risky).104- Always have rollback plan at every phase.105- Verify data integrity between phases (checksums).106- Run in staging first with production-like data volume.107108## Cross-Shard Queries109110### The Problem111Once data is sharded, joins across shards are expensive (scatter-gather).112113### Strategies114| Strategy | When to Use | Trade-off |115|----------|-------------|-----------|116| Denormalization | Frequent joins | Storage cost, write complexity |117| Pre-computed aggregations | Analytics, dashboards | Staleness, compute cost |118| Scatter-gather | Rare queries | Latency, complexity |119| Global tables (replicated) | Small reference data | Replication lag |120| Application-level joins | Low-volume cross-shard | Code complexity |121122### Denormalization Patterns123- Store user name alongside every order (avoid cross-shard user lookup).124- Embed category info in product documents.125- Maintain per-shard aggregation counters (updated async).126127### When Scatter-Gather Is Acceptable128- Admin queries (not user-facing, latency tolerant).129- Batch jobs (run off-peak).130- Infrequent search queries (use dedicated search index instead).131132## Consistent Hashing133134### How It Works1351. Hash ring with positions 0 to 2^32.1362. Each physical node gets multiple virtual nodes (tokens) on the ring.1373. Data routes to first node clockwise from its hash position.1384. Adding/removing node only affects adjacent range.139140### Virtual Nodes141- Each physical node owns 100-256 virtual nodes.142- More virtual nodes = more even distribution.143- Adding a physical node: assign new virtual nodes, migrate only affected ranges.144- Removing: redistribute its virtual nodes' ranges to neighbors.145146### Benefits Over Simple Modulo147| Aspect | Modulo (hash % N) | Consistent Hashing |148|--------|-------------------|-------------------|149| Add node | ~100% data moves | ~1/N data moves |150| Remove node | ~100% data moves | ~1/N data moves |151| Distribution | Depends on hash | Even with virtual nodes |152| Complexity | Simple | Moderate |153154## Geographic Sharding155156### Use Cases157- Data sovereignty (EU data stays in EU).158- Latency optimization (users read from nearest region).159- Regulatory compliance (GDPR, data residency laws).160161### Patterns162| Pattern | Reads | Writes | Consistency |163|---------|-------|--------|-------------|164| Write-local, read-local | Fast | Fast | Eventual (per-region) |165| Write-primary, read-any | Fast | Slower (cross-region) | Strong for writes |166| Multi-writer | Fast | Fast | Conflict resolution needed |167168### Conflict Resolution (Multi-Writer)169- Last-write-wins (simple, data loss possible).170- CRDTs (conflict-free, limited data types).171- Application-level merge (complex, most flexible).172- Operational transforms (collaborative editing).173174## Shard Routing175176### Routing Approaches1771. **Application-level**: App knows shard map, routes directly.1782. **Proxy layer**: Middleware (Vitess, ProxySQL) routes transparently.1793. **Client library**: SDK handles routing, app unaware.180181### Shard Map182```json183{184 "shards": [185 {"id": 0, "range": "0000-3FFF", "host": "db-shard-0.internal"},186 {"id": 1, "range": "4000-7FFF", "host": "db-shard-1.internal"},187 {"id": 2, "range": "8000-BFFF", "host": "db-shard-2.internal"},188 {"id": 3, "range": "C000-FFFF", "host": "db-shard-3.internal"}189 ]190}191```192193## Self-check194- [ ] Shard key meets all three criteria (cardinality, distribution, query alignment).195- [ ] No hotspots detected (per-shard metrics balanced).196- [ ] Cross-shard query strategy defined (denormalize, pre-compute, or scatter-gather).197- [ ] Resharding procedure documented and tested in staging.198- [ ] Consistent hashing with virtual nodes for even distribution.199- [ ] Application transparent to sharding (routing layer handles it).200- [ ] Per-shard monitoring (latency, storage, connections).201- [ ] Rollback plan exists at every migration phase.202- [ ] Geographic compliance verified if required.