Skip to main content
Pattern

Sharding (Horizontal partitioning)

Problem

Your dataset or write throughput has outgrown a single node. A single primary DB or single cache node can't hold the data or handle the QPS.

Context

You've maxed out vertical scaling. You need to split the data across multiple nodes so each node holds only a fraction — and traffic is distributed across nodes.

Solution

Pick a shard key (usually the primary key or a derived hash of it). For each key, deterministically map it to a shard using: (a) range partitioning, (b) hash partitioning, (c) consistent hashing, or (d) directory-based. Reads and writes route to the specific shard for the key.

Trade-offs

  • You lose easy cross-shard queries (JOIN across shards is hard; ORDER BY across shards requires scatter-gather)
  • Rebalancing is disruptive — hash mod N moves most keys when N changes; use consistent hashing to reduce this
  • Hot shards: if your shard key doesn't distribute evenly, one shard can be pegged while others idle
  • Operational complexity: N shards means N primaries to monitor, backup, and maintain
  • Multi-shard transactions require 2PC or Saga — huge complexity leap

Failure modes

  • Hot shard from a viral key (celebrity user, mega-tenant) — single shard swamped. Mitigate with per-key sub-sharding or in-memory hot-key promotion.
  • Cross-shard fan-out (searching across all users) becomes expensive. Mitigate with a separate index (search engine) or denormalized copy.
  • Shard imbalance from data growth in one shard's key range. Mitigate with periodic rebalancing.
  • A single shard down = a fraction of users see full failure (worse than everyone seeing partial degradation).

When to use

  • Your primary DB writes exceed ~10K/sec sustained
  • Your dataset exceeds ~1 TB per primary and vertical scaling is done
  • You can accept the complexity in exchange for horizontal write scale

When NOT to use

  • You're under 10K writes/sec — a bigger primary is cheaper and simpler
  • Your query patterns require frequent cross-key JOINs
  • You need distributed transactions across many entities — the complexity kills you