Partitioning and hot keys
Choose partition ownership and rebalance mechanics while accounting for skew, ordering, and the limits of adding shards.
On this page
The question for today
What you’ll understand
- Distinguish storage partitioning, distributed sharding, and replication.
- Calculate bottleneck capacity from a skewed partition workload.
- Design a hot-key mitigation without silently discarding ordering or transaction requirements.
A database team doubles the number of shards and sees almost no improvement because one popular tenant still owns half the writes. Partitioning spreads ownership according to a rule; it does not promise a balanced workload. Before choosing a hash function or a partition count, identify the unit that must stay together, the resource it consumes, and what happens when that unit becomes disproportionately popular. These questions also matter for partitioned event logs and feature stores.
Separate placement from replication
A table partition divides one logical table into portions, for example by date range. PostgreSQL can prune irrelevant partitions when a predicate permits it, reducing work without implying that partitions live on separate servers. Distributed sharding assigns portions to different owners. Replication makes additional copies of a portion and has its own consistency protocol. More replicas can increase some read capacity, but they do not automatically parallelize a single ordered write stream.
Range partitioning supports ordered scans and dropping old ranges, but an append-only workload can concentrate writes in the newest range. Hash partitioning distributes many independent keys more evenly in expectation, while scattering range queries. Composite schemes can combine time buckets with a hash within each bucket. State the query fan-out and ownership boundary explicitly: transactions or aggregates spanning many partitions introduce coordination and merging work that a single-partition benchmark omits.
Find the indivisible hot unit
Measure traffic and service cost per key and partition, not just key counts. Equal numbers of keys can hide one tenant with large values or expensive updates. If all events for a key must preserve one total order, hashing that key always sends them to one logical partition. Adding empty partitions cannot split the key while preserving the exact same ownership rule. A noisy key can also delay unrelated keys sharing its partition or worker.
Salting a hot key creates several subkeys and can spread commutative updates such as partial counters. Reads then aggregate the shards, and correctness depends on the merge operation and visibility contract. Salting an account balance or sequence-sensitive workflow without redesigning its transaction semantics can break invariants. Caching, batching, dedicated placement, admission control, or separating tenant workloads may be safer than splitting the logical key. Choose the remedy from the operation's algebra and ordering needs.
Rebalance ownership without losing the boundary
Moving a partition means coordinating a source, destination, and routing view while writes continue. A design may copy a snapshot, replay subsequent changes, establish a cutover boundary, and fence the old owner. Without fencing, delayed requests can write to an obsolete owner after the new owner is active. Without a complete replay boundary, acknowledged updates can be omitted from the destination. Reads also need a declared policy while migration is in progress.
In an event log, ordering is usually a per-partition guarantee; a consumer group's parallelism is bounded by assignment and the processing model. Increasing partition count can alter key-to-partition mapping depending on the producer's partitioner, so do not assume old and new events automatically retain one combined key order. Validate migrations with stable event identities, versioned routing, and reconciliation counts. Capacity planning should include the copy traffic and temporary duplicate storage rather than only the final balanced state.
Work it through
Explain why more shards did not help
Four shards each sustain 1,000 equal-cost updates/s. One key receives 40% of all updates and remains on one shard. Assume all remaining traffic can be balanced freely.
The hot shard receives at least 0.4λ updates/s from that key alone, even if no other keys are placed there.
Its capacity requires 0.4λ ≤ 1,000, so total throughput is bounded above by 2,500 updates/s before any headroom or other traffic on that shard.
The sum of shard capacities is 4,000 updates/s, but that aggregate bound cannot be achieved while the indivisible key imposes the stricter 2,500 bound.
Eight shards retain the same hot-key bound. If the operation supports two independently accumulated and correctly merged subkeys, each can carry about 20%, changing the bound; verify the semantics before doing so.
Aggregate capacity is not the operative limit when a single unsplittable key saturates its owner.
The living notebook
Explore the model
Interactive lab · queue
Inspect one overloaded owner
Model just one partition with arrival λ, capacity μ, and fluid backlog max(0,4+(λ−μ)t). Its separate M/M/1 residence readout needs Poisson arrivals and exponential service. It does not distribute keys, rebalance ownership, simulate a log, or infer spare capacity on other partitions.
- Fluid backlog
- 4
- Net rate · λ − μ
- −1 /s
- M/M/1 mean residence
- 1 s
Fluid backlog starts at 4 and follows max(0, 4 + (λ − μ)t). The separate M/M/1 residence-time formula assumes Poisson arrivals, exponential service and λ < μ. Parameter changes pause playback and recompute the model at the current elapsed time. Reset restores both parameters and returns time to zero. Playback starts paused. Adjust either parameter, then choose Play or Step.
Look forAn overloaded owner accumulates work even when the wider cluster has unused capacity.
Pause & reason
Check your understanding
Your turn
Try it yourself
A workload sends 50%, 25%, and 25% of equal-cost work to three partitions of capacity 600 work units/s each. Find the fixed-distribution throughput bound and compare it with aggregate capacity.
Take a moment to make a prediction or work it out on paper. Open a hint when you need one.
Give me a hint
Divide each capacity by its traffic fraction, then choose the smallest result.
Compare with the solution
The bounds are 600/0.5 = 1,200 and 600/0.25 = 2,400 for each other partition. Total rate is therefore at most 1,200 work units/s before headroom, despite aggregate capacity of 1,800. At that bound the first partition is saturated while the others each receive 300; effective balancing or semantic key splitting is needed to use the spare capacity.
Keep the idea
Take it with you
- Partitioning changes placement, while replication changes copies and failure behavior.
- A workload's hottest indivisible unit can dominate capacity despite more shards.
- Ownership migration requires replay boundaries, routing coordination, and fencing.
Read further
Original sources and deeper explanations to follow at your own pace.
Optional progress, saved in this browser when available. Revisit any lesson at any time.
Lesson not marked complete.