DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Newsletter
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Related

  • How to Prevent Retry Storms With Retry Budgets in Distributed Systems
  • Architecting Production AI Across Clouds: Patterns That Decide System Survival
  • How Performance Engineers Find and Fix Hidden System Bottlenecks
  • A Low-Latency Routing Pattern for Multiple Small Language Models

Trending

  • When Production Stops Moving: Running Claude Code Across a Distributed Enterprise Integration Team
  • Running TypeSafe AI's Jev Inside Neo4j for Confidence-Aware Sentiment Decisions
  • Designing Memory Architecture for Stateful AI Agents: Short-Term Context and Long-Term Persistence
  • Data Integration Landscape 2026: Event Streaming, API, and Batch in the Era of Agentic AI

Draft This article hasn't been published, so readers can't see it.

In moderation This article is waiting for review, so readers can't see it yet.

Deleted This article has been deleted, so readers can't see it.

  1. DZone
  2. Software Design and Architecture
  3. Performance
  4. Designing for Hot Keys: When Distributed Systems Stop Distributing

Designing for Hot Keys: When Distributed Systems Stop Distributing

Learn how to mitigate hot keys in distributed systems using bucketed writes, caching, replication, queues, and admission control.

By 
Jaswanth Mopathi
·
Nov. 13, 26 · Analysis
Post on X (opens in a new tab) Share on LinkedIn (opens in a new tab)
124 Views

Join the DZone community Save articles, join the discussion, and download Refcards and Trend Reports with a free account.

Join for free Already a member? Log in

Distributed systems usually spread data by hashing keys across nodes so no one node carries all the load. A hot key breaks that assumption. It is a key whose access volume greatly exceeds the volume of other keys during a given period. A global view counter or a popular item identifier can receive millions of reads or writes each second. Every request targets the same partition, even when the rest of the cluster has spare capacity.

The result is uneven load. One node reaches its CPU, network, thread, or connection limits while other nodes remain underused. Adding nodes does not solve the problem because traffic continues to resolve to the same partition. The overloaded shard becomes the bottleneck for a system that was intended to distribute work.

Hot keys also create failure risks. If a popular cache entry expires or its host fails, many requests can fall through to the backing data store at once. This cache breakdown can overwhelm the database and trigger broader failures. Teams should monitor access patterns and alert when one key represents an unusual share of traffic, latency, or bandwidth.

Split a Logical Key Into Physical Buckets

A common mitigation is to split one logical key into several physical buckets. Instead of updating a single counter, a writer chooses a bucket and updates that bucket. The combined value is calculated by reading and aggregating all buckets.

Java
 
public void increment(String key) {
    int bucket = ThreadLocalRandom.current().nextInt(NUM_BUCKETS);
    jedis.incr(key + ":" + bucket);
}
public int readTotal(String key) {
    int total = 0;
    for (int i = 0; i < NUM_BUCKETS; i++) {
        total += Integer.parseInt(jedis.get(key + ":" + i));
    }
    return total;
}


This pattern spreads writes across hash slots and nodes. The tradeoff is more work during reads. In Redis Cluster, a native `MGET`cannot read keys from different hash slots in one command. The client must issue individual reads, use parallel reads, or provide a scatter-gather layer that collects the bucket values. The aggregated total is also not an atomic snapshot because each bucket can be read at a different instant.

Bucketed counters work well when approximate totals are acceptable, such as views, metrics, or telemetry. They are less appropriate when every read requires a strictly current, exact value. The number of buckets should reflect peak write volume, expected read frequency, and the cost of aggregation.

Serve Read-Heavy Hot Keys From Local Memory

When a hot key is primarily read, an application cache can reduce pressure on the shared store. A short-lived in-memory cache lets many requests reuse a recently fetched value before another request reaches Redis or a database.

Java
 
private static final LoadingCache<String, String> HOT_KEY_CACHE =
    Caffeine.newBuilder()
        .expireAfterWrite(50, TimeUnit.MILLISECONDS)
        .build(key -> {
            try (Jedis jedis = JEDIS_POOL.getResource()) {
                return jedis.get(key);
            }
        });


With this setup, most reads can be served from memory, and cache misses fetch the current value from Redis. The short expiration bounds the staleness window. This is useful when the business can tolerate a briefly outdated response in exchange for much lower read pressure on the shared data store.

Systems can also use layered caches. A content delivery network or edge cache can absorb public traffic, followed by an application cache, then a distributed cache, and finally the durable store. Each layer should have a clear expiration policy and a plan for cache invalidation. The goal is to keep repeated reads from reaching the most constrained shared component.

Replicate Values When Reads Are More Important Than Writes

Another option for a read-dominated hot key is replication. The system stores several copies of the logical value on different shards, then distributes reads across the copies.

Java
 
int idx = ThreadLocalRandom.current().nextInt(REPLICA_COUNT);
String replicaKey = originalKey + ":" + idx;
String value = jedis.get(replicaKey);


Replication can increase read capacity because different nodes serve independent requests. It adds work to writes because every replica must be updated. If an update fails for one replica, callers can see different values depending on the chosen key. This approach is useful when stale or temporarily inconsistent reads are acceptable. It needs an explicit repair strategy for failed replica updates.

Smooth Write Spikes With Queues and Admission Control

A hot key with a high write rate may need a different approach. Instead of applying every update immediately, the service can publish updates to a queue and let workers batch or aggregate them before writing to the shared store. This smooths spikes and protects the storage layer, but it adds write latency and creates a delay before the final value is visible.

Rate limiting and backpressure can protect the system when a sudden surge would otherwise overwhelm one partition. These controls should preserve important traffic first and reject or delay work that can safely wait. The correct policy depends on whether the key represents a counter, inventory, a payment state, or another domain with different consistency requirements.

Choose the Tradeoff Explicitly

Every hot key mitigation trades one property for another. Buckets increase read work and make aggregate snapshots non-atomic. Application caching introduces staleness. Replication increases write cost and requires reconciliation. Queues delay visibility. These tradeoffs are often preferable to letting one shard become a single point of congestion.

The right design starts with the semantics of the key. Decide whether the value must be exact, how long it can be stale, whether writes can be delayed, and what happens when the shared store is unavailable. Then measure the key’s read rate, write rate, payload size, and partition utilization. A mitigation that is safe for a view counter can be incorrect for inventory or payment state.

Hot keys are a normal condition in systems with uneven demand. Monitoring should detect them early, and the architecture should provide a way to redistribute load before one partition limits the entire service. With bucketed writes, local caching, replication, queues, and admission control, teams can turn a concentrated source of traffic into a managed capacity decision instead of a cluster-wide incident.

systems Data Types Performance

Opinions expressed by DZone contributors are their own.

Related

  • How to Prevent Retry Storms With Retry Budgets in Distributed Systems
  • Architecting Production AI Across Clouds: Patterns That Decide System Survival
  • How Performance Engineers Find and Fix Hidden System Bottlenecks
  • A Low-Latency Routing Pattern for Multiple Small Language Models

Partner Resources

×

Comments

Loading comments

The comments didn't load

Please try again in a moment.

Likes

Loading

The next likes didn't load. Please try again.

The likes didn't load

Please try again in a moment.

See who liked this

Log in or join DZone for free to see who liked this article.

Log in Join for free
  • RSS
  • X
  • Facebook

ABOUT US

  • About DZone
  • Support and feedback
  • Community research

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 215
  • Nashville, TN 37211
  • [email protected]

Let's be friends:

  • RSS
  • X
  • Facebook