What it is
A hot key is a partition key that receives disproportionately high read or write traffic, causing a single physical shard to become a bottleneck while the rest of the cluster sits idle.
When you care
Hot key problems appear whenever a system design involves a distributed NoSQL store — DynamoDB, Cassandra, HBase — and the interviewer introduces a skewed access pattern: a trending topic, a viral post, a product promoted during a flash sale.
The trap is saying “we’ll shard by X” and moving on. Consistent hashing routes all requests for a given partition key to a single physical node. No amount of horizontal scaling helps if every request goes to the same node. The probing question is always: what happens when one key gets 100× the traffic of any other?
Root cause
Distributed NoSQL systems route data by computing a token from the partition key:
Token = Hash(Partition Key)
That token places the key on exactly one node in the ring. When a business
event concentrates traffic on one key — a date like 20260601 during a sale,
or an entity like Trump during a news cycle — the single node holding that
token receives every read and write. The rest of the cluster is irrelevant.
The overloaded node hits its CPU ceiling, triggers GC pauses, and causes
cluster-wide timeout cascades. On DynamoDB, this also hits the hard per-partition
limit (1,000 WCU / 3,000 RCU), which no amount of provisioned capacity at
the table level can bypass.
Mitigation patterns
| Pattern | Mechanism | Read cost | Write cost | Best for |
|---|---|---|---|---|
| Salting | Append a random suffix [0, N) to the key | Scatter-gather across N shards | Distribute to 1 of N | Static, unpredictable hot keys |
| Deterministic sharding | Append a derived suffix (e.g. Hash(item_id) % N) | Precise pruning — query only the right shard | Distribute to 1 of N | Keys with a stable natural sub-attribute |
| Time-bucketed routing | Store (key, date) → shard_count in a metadata table | Parallel query only the shards that existed on that date | Write to shards for the current date’s count | Time-windowed data models |
| Epoch versioning | Config center stores version → shard_count; new writes use the latest version | Must query all versions until rebinned | Write to shards for the current version | Data without natural time boundaries |
| Hotspot caching | Detect hot keys at the gateway layer and absorb reads in Redis/local memory | Near-zero DB cost once cached | No write benefit | Read-heavy hot keys with tolerable staleness |
Salting (partition splitting)
Append a random suffix in [0, N) to the partition key at write time:
shard_id = rand() % N
physical_key = original_key + "#" + shard_id
Reads must scatter across all N shards and merge the results in the application layer — a scatter-gather that adds latency and application complexity. Use this when hot keys emerge unpredictably and you cannot derive a natural sub-attribute. The cost of scatter-gather is the price of eliminating a data model dependency on which keys will be hot.
Deterministic sharding
Derive the suffix from a stable, fine-grained attribute of the data:
shard_id = Hash(item_id) % N
physical_key = original_key + "#" + shard_id
Reads can prune precisely: if the query specifies the sub-attribute, compute the shard directly and read one shard instead of N. This avoids scatter-gather entirely. The tradeoff is that the sharding attribute must exist in the data model and must be present in all queries. If you need to query by the hot key alone without the sub-attribute, you still scatter.
Time-bucketed metadata routing
Store a lightweight metadata table mapping (key, date) to a shard count:
| Key | Date | Shard count |
|---|---|---|
Trump | 2010-01-01 | 1 |
Trump | 2016-11-08 | 10 |
Trump | 2026-06-06 | 3 |
At write time, look up the shard count for today and distribute across that many shards. At read time, look up the shard count for the target date — not today’s — and query only that many shards in parallel. This avoids the read amplification that comes from using a static maximum: a query for 2010 data fans out to 1 shard, not 10. Add one entry when hot-key pressure grows; lower it when traffic subsides. Works cleanly for data models with a time dimension in the partition key.
Epoch versioning with async rebinning
When data has no natural time boundary, use a version number managed by a configuration store (Consul, ZooKeeper):
v1 → shard_count: 3
v2 → shard_count: 10 ← current
New writes always use the current version’s shard count. Reads must query all active versions until data from old versions is migrated. An async rebinning service gradually reads old-version data and re-writes it under the current version’s routing. Once a version has been fully rebinned, remove it from the active list and the read fan-out shrinks back down. The rebinning window is the cost — during it, reads are amplified across all live versions.
Hotspot detection and caching
Deploy a read interception layer in front of the database:
- A gateway (application-level or service mesh) tracks per-key QPS with an LRU counter.
- When a key exceeds a QPS threshold, mark it as hot and route subsequent reads to a Redis cluster or local in-process cache.
- The database sees only the write path and the occasional cache miss refresh.
This is a read-only mitigation and tolerates some staleness. It does not help with write hot keys, and it requires the application to define a coherent cache invalidation strategy. Pair it with TTL-based expiry when strong consistency is not required.
Tradeoff summary
Pick salting when hot keys emerge unpredictably and you accept scatter-gather on reads.
Pick deterministic sharding when a stable sub-attribute exists in the data model and queries always include it — you get scatter-free reads.
Pick time-bucketed routing when your partition key naturally includes a date or time bucket and traffic patterns correlate with time.
Pick epoch versioning when data has no time boundary and you can afford an async migration window during scaling events.
Pick hotspot caching as a read-side overlay on top of any of the above, or as a fast mitigation before a permanent sharding change is deployed.
Never assume that adding capacity to the NoSQL cluster eliminates a hot key. More nodes do not help if consistent hashing keeps routing all requests for one key to the same node.
Related
- Walkthrough: Designing a Social Media Feed — hot key pressure is central to the fan-out-on-write vs. fan-out-on-read tradeoff.
- Reference: SQL vs NoSQL Schema Design — the partition key choice that creates the hot key problem in the first place.
- Reference: Caching Patterns — hotspot caching builds on cache-aside and read-through fundamentals.