Data Partitioning & Sharding Strategies
Replication copies the same data everywhere for availability. Sharding splits different data across machines because no single one can hold it all.
Intermediate
| Approach | How it splits data | PlateRoute example |
|---|---|---|
| Vertical sharding | Different tables (or column groups) live on different database instances. | The orders table lives on one database, restaurant_menus on another, driver_locations on a third. |
| Horizontal sharding | The same table is split row-wise across multiple identically-structured databases. | The orders table with 500M rows is split into 8 shards, each holding roughly 1/8 of the orders. |
| Strategy | How it works | Strength | Weakness |
|---|---|---|---|
| Key-range sharding | Each shard owns a contiguous range of the key (e.g. order IDs 1–1M go to Shard 1, 1M–2M to Shard 2). | Efficient range queries — "give me all orders from March" hits one or few shards. | Hotspots: if today's orders are all recent IDs, one shard absorbs nearly all current write traffic. |
| Hash-based sharding | shard = hash(key) % num_shards — the hash spreads keys pseudo-randomly across shards. | Even load distribution, no hotspots from sequential keys. | Range queries become expensive (data isn't ordered by key across shards); resharding when the shard count changes moves most of the data. |
shard_id = hash(order_id) % 8
order_id = 918203 -> hash(918203) % 8 = 3 -> Shard 3
order_id = 55010 -> hash(55010) % 8 = 6 -> Shard 6
hash(key) % n has a nasty property: changing n (adding or removing a shard) changes the result of the modulo for nearly every key, forcing almost all data to move at once. Consistent hashing fixes this, and is covered in full depth in Consistent Hashing — the short version is that both keys and shards are placed on a hash ring, so adding or removing one shard only reassigns the small slice of keys nearest to it, not the whole dataset.| Strategy | How it works |
|---|---|
| Fixed number of partitions | Create far more logical partitions than current physical nodes up front (e.g. 1,000 partitions across 10 nodes); as nodes are added, reassign whole partitions to them rather than resplitting data. |
| Dynamic partitioning | When a partition grows past a size threshold, split it in two and move one half to a different node — adapts to data volume automatically, at the cost of added complexity while serving live traffic. |
| Partitions proportional to nodes | Keep the number of partitions proportional to the number of nodes; when a new node joins, it takes a random slice of partitions from existing nodes rather than the whole dataset reorganizing. |