Rendezvous hashing vs consistent hashing vs mod N: an interactive comparison
When keys are spread over servers and servers come and go, the placement rule decides how many keys have to move. hash(key) mod N moves almost all of them. A consistent hashing ring moves only the necessary share but needs many virtual nodes to stay balanced. Rendezvous hashing, also called highest random weight, gets both with a simpler rule: every server scores the key with a hash, and the highest score wins.
The playground places 1,200 keys on six servers three ways. Remove a server or add one, change the ring’s virtual nodes, and compare how many keys move and how even the load stays.
1,200 keys spread over six servers. Server 3 leaves; the least that can move is 16.7% (server 3’s share). Hash mod N moves 82.8%: changing N reshuffles almost everything. The ring with one point per server moves 40.3%: only server 3's keys, but its single point happened to own that much of the ring, and every one of them lands on its one neighbour, now holding 2.5 times the average. Rendezvous hashing moves 17.5%, only server 3's keys, spread evenly over the other five, with no virtual nodes; each lookup hashes the key once per server.
- Keys moved
- 82.8%
- Busiest server
- 1.11× average
- Keys moved
- 40.3%
- Busiest server
- 2.55× average
- Keys moved
- 17.5%
- Busiest server
- 1.09× average
Why mod N fails and the ring needs help
With mod N, changing N from 6 to 5 changes the answer for about 83% of keys, when only server 3’s sixth needed to move. Caches go cold and databases reshuffle almost everything. A consistent hashing ring moves only the keys between the changed point and its predecessor, but with one point per server the gaps are uneven: before anything changes, one server already holds 2.4 times its share; when server 3 leaves, all of its keys fall to a single neighbour; a newly added server can catch just one key. Giving each server 100 virtual points evens this out, at the cost of a table of 600 points to store and search.
How rendezvous hashing works
For each key, compute hash(key, server) for every server and pick the largest. Each server’s score is independent, so removing server 3 only changes the answer for keys where server 3 had the top score, 17.5% here, and those keys go to whichever server had the second-highest score, which is effectively random: the load spreads evenly over the remaining five. Adding a server takes an even slice from every existing one. No virtual nodes, no ring to maintain, and taking the top few scores gives a natural list of replicas.
The cost is lookup work: N hashes per key instead of one hash and a binary search. With tens of servers that is nothing; with thousands, use a hierarchy (pick a group, then a server within it) or a ring. Weighted variants handle servers of different sizes. Rendezvous hashing is used in CDN and proxy routing, for example to decide which cache server holds an object, and in systems such as Apache Ignite.
Rendezvous hashing in code
import hashlib
def score(key: str, server: str) -> int:
return int.from_bytes(hashlib.blake2b(f"{key}|{server}".encode(), digest_size=8).digest(), "big")
def owner(key: str, servers: list[str]) -> str:
"""Rendezvous (highest random weight) hashing: every server scores the key, the highest wins."""
return max(servers, key=lambda s: score(key, s))
def owners(key: str, servers: list[str], replicas: int = 3) -> list[str]:
"""Replicas come for free: take the top few scores."""
return sorted(servers, key=lambda s: score(key, s), reverse=True)[:replicas]In a system design interview
When you shard a cache or route requests to stateful nodes, name the rule: “Each edge proxy maps a URL to one of the 40 cache servers in its region with rendezvous hashing, so all proxies agree without coordination, and when a server fails only its objects move, spread evenly over the rest. With 40 servers the 40 hashes per request are negligible.” Expect the follow-ups: what happens to hot keys, how membership changes reach every proxy, and when you would choose a ring instead.
Read the guide to consistent hashing or sharding and partitioning, see hot keys, or watch a strong candidate design a distributed cache.
Questions people ask
What is rendezvous hashing?
A way to assign keys to servers in which every server computes a score, hash(key, server), and the key goes to the server with the highest score. It is also called highest random weight hashing. Everyone who knows the server list computes the same answer without coordination.
How does rendezvous hashing compare with consistent hashing?
Both move only about 1/N of keys when a server joins or leaves. Rendezvous hashing spreads load evenly without virtual nodes and redistributes a departed server’s keys over all remaining servers, while a ring needs many virtual nodes for balance. The ring’s lookup is a binary search; rendezvous needs one hash per server.
Why is hash mod N bad for distributed caches?
Because changing the number of servers changes the result for almost every key: going from 6 to 5 servers remaps roughly 5 in 6 keys. Caches go cold and data has to be reshuffled, when only the departed server’s keys needed to move.
Why does a consistent hashing ring need virtual nodes?
With one point per server, the arcs between points are uneven, so some servers own far more of the ring than others, and a departing server’s keys all go to its single neighbour. Many virtual points per server average the arcs out and spread a departing server’s keys around the ring.
How do you pick replicas with rendezvous hashing?
Sort the servers by their score for the key and take the top few. The list is stable: when a server leaves, each key’s remaining replicas keep their order and the next-highest server fills the gap.
What is the cost of rendezvous hashing?
A lookup computes one hash per server, which is O(N). That is negligible for tens or hundreds of servers. For very large clusters, a hierarchical or skeleton-based variant first picks a group and then a server within it.
Where is rendezvous hashing used?
In CDN and proxy layers that route objects to cache servers, in distributed caches and storage systems such as Apache Ignite, and in load balancers that need sticky routing without shared state. GitHub’s load balancer and many CDNs use variants of it.