CONCEPT SHEET · Concepts

Database Sharding

One-liner: Split one logical dataset across many nodes by a shard key so writes and storage scale horizontally; you pay with cross-shard queries and resharding.

ArticleConcepts© Arthur Bernier Jr592 words1 code block

Say this#

How it works#

TEXT
request(user_id=1234) -> router (app lib / proxy like Vitess, Citus coordinator)                           -> shard = hash(user_id) % 4096 (logical) -> node 7 (physical)
  1. Pick a shard key that appears in nearly every query and spreads evenly (user_id, tenant_id).
  2. Use many logical shards from day one; map logical → physical in config (Zookeeper/etcd).
  3. Colocate everything for one entity on the same shard so transactions stay local.
  4. Global/secondary indexes: either per-shard (scatter-gather) or a separate global index table (DynamoDB GSI, async).
  5. Reshard by moving whole logical shards: double-write or snapshot + replay changelog, then flip the mapping.

Trade-offs#

ChoiceProCon
Hash shardingEven distributionRange queries become scatter-gather
Range shardingRange scans, orderedHot spots on sequential keys (timestamps, auto-increment)
Directory shardingArbitrary placement, easy movesLookup hop; the directory must be HA and cached
Shard by tenant/userLocal transactions, simpleBig tenants become hot shards
Vertical partitioning firstSimple, no cross-shard joins within a domainEach service DB still hits the single-node ceiling
Not sharding (scale up + replicas)Simplest; often enough to tens of TBEventually a wall for writes

Numbers#

  • Rule of thumb: start thinking about sharding when a single primary passes roughly a few TB or ~10k+ sustained writes/s; prefer vertical scale, caching, and read replicas first.
  • Pre-split into 2^10 to 2^12 logical shards; physical node count can grow by moving whole logical shards.
  • Instagram-style ID: 41 bits time, 13 bits logical shard (8192 shards), 10 bits sequence.

In the interview#

See also