PrepZone Logo
PrepZone

Consistent Hashing

Add or remove cache nodes without remapping every key — the ring that powers distributed caches.

Read these first

The problem with modulo hashing

Java
3 cache nodes, key "user:42"
  slot = hash("user:42") % 3  →  node 1

Add node 4:
  slot = hash("user:42") % 4  →  node 2   ← MOVED! cache miss storm

When StreamHub expanded Redis from 4 to 6 nodes using naive modulo, cache hit ratio dropped from 92% to 41% until keys repopulated — a classic cache stampede on the database.

The hash ring

Hash ring0 … 2^32-1
Node Akeys 0–25%
Node Bkeys 25–50%
Node Ckeys 50–75%
Node Dkeys 75–100%

New node E joins → only ~1/N keys move, not all keys.

Adding a node only remaps keys adjacent to it on the ring.

Ring mechanics

  1. Hash space is a fixed ring (0 to 2³²−1 or 0 to 1.0).
  2. Each node is placed at one or more positions on the ring (via hash of node ID).
  3. Each key is hashed to a position on the ring.
  4. Walk clockwise from the key's position — the first node encountered owns the key.
  5. Adding a node steals only keys between its predecessor and itself.

Only keys in the affected arc move — typically 1/N of total keys when adding one of N nodes.

Virtual nodes (vnodes)

Physical machines get multiple positions on the ring for even distribution:

Java
Physical node A → vnode A0, A1, A2, A3 on ring
Physical node B → vnode B0, B1, B2, B3 on ring

Without vnodes, uneven key density clusters on a few nodes. Redis Cluster and Dynamo use vnode-style partitioning.

Java
# Redis Cluster — key must include hash tag for multi-key ops
SET user:{42}:session abc123
GET user:{42}:profile
# {42} ensures both keys land on same slot

The {...} hash tag forces related keys to the same slot — required for atomic multi-key operations.

Consistent hashing use cases

SystemWhat is hashedPurpose
Distributed cacheCache keyRoute key to correct Redis/Memcached node
Load balancerClient IP or session IDSticky routing with minimal remapping
Database shardingPartition key (creator_id)Stable shard assignment
CDN / object storeObject keyEven distribution across storage nodes
  • Distributed cache

    What is hashedCache key
    PurposeRoute key to correct Redis/Memcached node
  • Load balancer

    What is hashedClient IP or session ID
    PurposeSticky routing with minimal remapping
  • Database sharding

    What is hashedPartition key (creator_id)
    PurposeStable shard assignment
  • CDN / object store

    What is hashedObject key
    PurposeEven distribution across storage nodes

Adding and removing nodes

Adding a node:

Java
Before:  keys K1–K5 → nodes A, B, C
Add D between B and C:
  Only keys that mapped to C and fall between B and D now map to D
  ~1/(N+1) keys move

Removing a node:

Keys owned by the removed node transfer to its clockwise successor. Plan capacity so successors absorb the load.

Java
# StreamHub cache expansion runbook
steps:
  - add_new_node_with_vnodes
  - wait_for_key_migration_background
  - monitor_hit_ratio_recovery
  - remove_old_node_if_replacing
expected_hit_ratio_dip: temporary_5-10_pct

Comparison with alternatives

AspectModulo hashConsistent hash
Node add/remove~100% keys remap~1/N keys remap
ImplementationTrivialRing + vnodes + gossip
Load balanceEven if hash uniformNeeds vnodes for even spread
Used byToy examplesRedis Cluster, Cassandra, Dynamo
  • Node add/remove

    Modulo hash~100% keys remap
    Consistent hash~1/N keys remap
  • Implementation

    Modulo hashTrivial
    Consistent hashRing + vnodes + gossip
  • Load balance

    Modulo hashEven if hash uniform
    Consistent hashNeeds vnodes for even spread
  • Used by

    Modulo hashToy examples
    Consistent hashRedis Cluster, Cassandra, Dynamo

Hot keys and mitigation

Consistent hashing does not fix hot keys — if every request hits video:viral_001, one node still melts.

Hot key mitigations

  • Local cache on app server for ultra-hot keys.
  • Key splitting — video:viral_001:copy0 … copy7 spread load.
  • Read replicas behind the owning node.
  • Pre-warm cache before anticipated traffic spikes.
Java
# Hot key fan-out read (pseudocode)
def get_view_count(video_id: str) -> int:
    if is_viral(video_id):
        replica = random.randint(0, 7)
        return cache_get(f"views:{video_id}:r{replica}")
    return cache_get(f"views:{video_id}")

Rendezvous hashing (alternative)

Highest Random Weight (HRW) hashing picks the node with the highest hash(node, key) score. Simpler than a ring for small node counts; consistent hashing scales better for large dynamic clusters.

Quick recall

Everything you need if you only revisit this box.

  • Modulo hashing remaps most keys when node count changes; consistent hashing minimises movement.
  • Keys and nodes sit on a ring; each key belongs to the next node clockwise.
  • Virtual nodes spread load evenly across physical machines.
  • Redis Cluster uses hash slots; {tag} groups related keys on one slot.
  • Used for distributed caches, shard routing, and sticky load balancing.
  • Hot keys are a separate problem — split keys or replicate reads.

Test yourself

Answer these before moving on — recall is what makes it stick.