SD System Design In Depth
0%
lesson system-designpartitioninghashing

Consistent hashing

Module 2.2: NoSQL Architectures, Partitioning & IDs Updated Sep 17, 2026
📄 Cheat Sheet
Consistent Hashing | Algorithms You Should Know #1
ByteByteGo Consistent Hashing | Algorithms You Should Know #1 Watch on YouTube ↗

The cleanest visual explanation of the ring, why modulo hashing remaps most keys, and how virtual nodes fix skew.

0:00 / --:--

Concrete scenario

A cache fleet adds a node without wanting modulo hashing to remap most keys.

Mechanics

Place keys and weighted virtual nodes on a ring and route each key to its successor. Under uniform assumptions, adding one similarly weighted node moves an expected fraction near 1/(N+1), rather than the large fraction changed by modulo hashing.

Failure mode

A hot key remains hot, stale membership views route clients differently, and moved keys cause misses until warmed or replicated. Virtual nodes reduce expected skew but do not guarantee a fixed balance.

Trade-off

Consistent hashing limits topology-change movement and supports weighting, but requires membership distribution, replication, skew monitoring, and careful failure handling.

Worked example: modulo vs ring when adding a cache node

Suppose 10M cached keys sit on 10 nodes, and you add an 11th.

  • hash(key) mod N: a key stays only if h mod 10 == h mod 11, which holds for about 1 in 11 keys. So about 91% of keys (9.1M) move, and the cache hit rate collapses to about 9%. The database behind it absorbs a miss storm.
  • Consistent hashing: the new node takes over about 1/11 of the ring, so about 909k keys (9%) move, and hit rate dips only about 9 points.

How many virtual nodes?

With V virtual nodes per server, the standard deviation of load is roughly proportional to 1/sqrt(V).

Vnodes per serverApproximate load spread (max vs mean)Ring size for 10 servers
1Often 2-3x the mean10 points
10About 1.3-1.5x100 points
100-256About 1.1x1,000-2,560 points

Cassandra historically defaulted to 256 vnodes per node (num_tokens), and 4.0 changed the default to 16 with a smarter token allocator, trading perfect balance for faster repairs and streaming.

Lookup implementation

Store the vnode positions in a sorted array. To route a key, compute h = hash(key), binary-search for the first position at or after h, and wrap around to index 0 if past the end. That is O(log(N x V)), microseconds even for thousands of points. For replication, keep walking clockwise to collect the next R distinct physical nodes.

flowchart LR K["Key hash 0x7A"] --> S["Binary search sorted ring"] S --> N1["First vnode at or after 0x7A: node B"] N1 --> R2["Next distinct node: D (replica 2)"] R2 --> R3["Next distinct node: A (replica 3)"]

Alternatives

  • Rendezvous (HRW) hashing: score every node with hash(key, node) and pick the highest. Also minimal movement, no ring to maintain, O(N) per lookup.
  • Jump consistent hash (Google): no memory and perfectly balanced, but nodes can only be added or removed at the end. Good for numbered shards.
  • Fixed slots: Redis Cluster uses 16,384 hash slots assigned to nodes, which is simpler and explicit to rebalance.
  • Bounded loads (Google, Vimeo): consistent hashing with a capacity cap per node to limit hot-node overload.
Check yourself Question 1 of 3
Role of virtual nodes recall
From: Mechanics

In consistent hashing, why do systems place many weighted virtual nodes per physical server on the ring?

Consistent Hashing Ring Visualizer
O(log N) Route

Observe how keys are distributed along a 360° circular hash ring. Add or remove nodes to see minimal key rebalancing in action!

Nodes: 4 | Virtual Nodes/Node: 3
0°
90°
180°
270°
Ring Size: 2^32
Clockwise Lookup
// Consistent Hashing Event Log
[INIT] Cluster established with Node_A, Node_B, Node_C, Node_D.
[READY] Binary search (upper_bound) active for ring lookups.

Key Takeaways

Consistent hashing limits expected remapping under topology changes.
Virtual nodes reduce expected skew but do not guarantee balance.
Hot keys, membership drift, and warming still need explicit handling.
Was this lesson helpful? Spot an issue or have a suggestion? Let us know on GitHub.
Report an issue