appshard 0shard 1shard 21def shard_for(key):2 return key % 34shard 3one serverc7 · 30c12 · 45c5 · 20c9 · 15c4 · 50c11 · 407 % 3 = 1608060200
Back row: the shop app and the shard serversFront: the router's rule and the one server the table started onChips are rows (c<customer_id> · total); envelopes are queries; discs are answersAt the back: the shop app and the shard servers. In front: the router's rule and the one server the orders table lived on before it was split. Each row chip shows its shard key and total (c7 · 30 is customer 7, total 30). The rule customer_id % 3 sends every row to one shard; a query that names the key goes to one shard, and one without it asks every shard and adds up the parts. A busy key makes one shard a hot spot, and adding a shard with a plain % rule moves 5 of the 6 rows. To keep the arithmetic checkable, the figure uses customer_id % 3 directly. Real systems hash the key first, so neighbouring keys such as 7 and 8 land far apart; PostgreSQL’s hash partitioning takes the hash value, then the remainder.

Why split a table

  1. A shop keeps every order in one table on one server. As it grows, every write lands on that one machine until it runs out of disk and speed. Replicas (copies) can share the reads, but not the writes.

Asking a sharded table

The hard parts

What happens

;; step 1/10 · one
table orders, all on one server
  id  customer_id  total
  1   7            30
  2   12           45
  3   5            20
  4   9            15
  5   4            50
  6   11           40

every INSERT and UPDATE goes to this one server
replicas copy it, so they help with reads only
a chip in the figure:  c<customer_id> · <total>

To keep the arithmetic checkable, the figure uses customer_id % 3 directly. Real systems hash the key first, so neighbouring keys such as 7 and 8 land far apart; PostgreSQL’s hash partitioning takes the hash value, then the remainder. With a plain "key % N" rule, changing N moves most rows: here 5 of 6. Systems such as Citus, Vitess and Cassandra split the data into many more pieces than servers (or use consistent hashing), so adding a server moves only some whole pieces.