Instagram's Sharding Journey
Horizontal Sharding, database sharding, partitioning, PostgreSQL scaling, consistent hashing, user_id sharding, distributed databases, and horizontal scalability are the core concepts behind Horizontal Sharding: Splitting Your Database Across Multiple Servers. These techniques are used when a single database server reaches its limits for write throughput, storage, or concurrent users. A famous real-world example is Instagram, which moved from a single PostgreSQL instance to a sharded architecture using user_id-based consistent hashing, allowing user data such as photos, likes, comments, and follower relationships to be distributed across multiple database servers and enabling the platform to scale from millions to billions of users.
When Replication Is Not Enough
Replication scales reads but not writes - all writes still go to one primary. When you have billions of rows and thousands of writes per second, one server cannot keep up. Sharding splits the data itself across multiple independent database servers.
Replication (scales reads): Sharding (scales reads AND writes):
All writes Read traffic Shard A: Users 1-1M
| / | \ (independent DB)
+--------+ R1 R2 R3 Shard B: Users 1M-2M
| Primary| (independent DB)
+--------+ Shard C: Users 2M-3M
(independent DB)
Bottleneck: 1 primary Each shard handles its own
handles ALL writes reads AND writes independentlySharding Strategies
1. RANGE-BASED SHARDING
Shard by ranges of the key value
Shard A: user_id 1 - 1,000,000
Shard B: user_id 1,000,001 - 2,000,000
Shard C: user_id 2,000,001 - 3,000,000
Pros: Simple, range queries stay on one shard
Cons: Hot spots! New users (high IDs) are more active,
so the last shard gets hammered.
2. HASH-BASED SHARDING
shard = hash(user_id) % num_shards
hash(42) % 3 = 0 --> Shard A
hash(73) % 3 = 1 --> Shard B
hash(128) % 3 = 2 --> Shard C
Pros: Even distribution (no hot spots)
Cons: Range queries (WHERE id BETWEEN 1 AND 1000)
must hit ALL shards. Adding shards = reshuffles.
3. DIRECTORY-BASED SHARDING
A lookup table maps each key to its shard
Lookup Table:
user_id 42 --> Shard B
user_id 73 --> Shard A
user_id 128 --> Shard C
Pros: Maximum flexibility, easy re-sharding
Cons: Lookup table is a bottleneck and SPOF
4. GEOGRAPHIC SHARDING
US users --> US-East shard
EU users --> EU-West shard
APAC --> Singapore shard
Pros: Data locality, GDPR compliance
Cons: Cross-region queries are expensiveThe Costs of Sharding
What sharding breaks:
1. Cross-shard JOINs:
User on Shard A follows User on Shard C
--> JOIN requires network hop between shards
--> 10-100x slower than local JOIN
2. Cross-shard transactions:
Transfer money from User A (Shard 1) to User B (Shard 3)
--> Requires distributed transaction (2PC)
--> 10-50x slower, complex failure handling
3. Re-sharding:
Adding shard D to (A, B, C) requires migrating data
--> Weeks of planning, careful migration, potential downtime
4. Application complexity:
Every query must know: "which shard has this data?"
--> Shard-routing logic in application code
--> OR use a proxy (Vitess, Citus, ProxySQL)
5. Aggregation queries:
SELECT COUNT(*) FROM users --> must query ALL shards
ORDER BY created_at LIMIT 10 --> merge-sort across shardsShard Key Selection
The shard key is the single most important decision. A bad shard key creates hot spots, forces cross-shard queries, and makes re-sharding painful.
Good shard keys: Bad shard keys:
user_id (for user data) created_at (hot spot on
- Even distribution latest time range)
- Most queries include it
- Natural isolation country (US shard gets 50%
of traffic = hot spot)
tenant_id (for SaaS)
- Perfect isolation auto-increment id
- No cross-tenant queries (new rows always go to
the last shard)Alternatives to DIY Sharding
Tool/Service What It Does When to Use
-------------- ---------------------------- ----------------------
Citus (PG ext) Transparent sharding for PG Multi-tenant SaaS
Vitess MySQL sharding proxy Large MySQL deployments
CockroachDB Distributed SQL (auto-shard) New apps needing scale
AWS Aurora Managed auto-scaling storage AWS-native apps
PlanetScale Managed Vitess (MySQL) MySQL with zero-downtimeInterview Tip
When an interviewer asks about sharding, start with: 'I would avoid sharding as long as possible because it adds enormous complexity. A single PostgreSQL instance with proper indexing handles hundreds of millions of rows. I would scale reads with replicas first. If we truly need write scaling beyond what one server handles, I would shard by user_id (or tenant_id for SaaS) using hash-based distribution for even load. I would use a sharding proxy like Vitess or Citus to minimize application-level changes.'
Key Takeaway
Sharding splits data across multiple servers for write scaling and storage capacity. Choose sharding strategy based on access patterns. Avoid sharding until necessary - it adds enormous complexity. When you must shard, pick a key that distributes load evenly and minimizes cross-shard queries.
