Skip to content

Rendezvous Hashing Lookup

Map a key to the node that receives the highest hash score for that key.

Rendezvous hashing, also called highest random weight hashing, maps a key to the node with the highest score for that key. Each candidate node is scored together with the key, and the node with the maximum score is selected.

You use it in distributed systems when keys must be assigned to changing sets of nodes with minimal movement and no shared hash ring.

Problem

Given a set of nodes NN and a key kk, choose the node responsible for kk.

Model

For every node vNv \in N, compute a score:

s(v,k)=h(v,k) s(v, k) = h(v, k)

The selected node is:

argmaxvNs(v,k) \operatorname*{argmax}_{v \in N} s(v, k)

The hash function should distribute scores uniformly.

Algorithm

rendezvous_lookup(nodes, k):
    best_node = null
    best_score = -infinity

    for each node in nodes:
        score = h(node, k)
        if score > best_score:
            best_score = score
            best_node = node

    return best_node

Example

Suppose the nodes are:

N=A,B,C N = {A, B, C}

For key "user:42", assume the scores are:

nodescore
A18
B73
C41

The highest score is 73, so the key maps to node B.

If node B is removed, the key moves to the remaining node with the next highest score, which is C in this example.

Correctness

The algorithm computes the score for every candidate node and keeps the maximum. Therefore it returns exactly the node defined by the rendezvous hashing rule.

When a node is added or removed, only keys for which that node wins or previously won need to move. Other keys keep the same winner.

Complexity

operationtime
lookupO(n)O(n)

The lookup scans all nodes. Optimized variants reduce this cost for large node sets.

Space

O(1) O(1)

Lookup uses only the current best node and score, aside from the node list itself.

When to Use

Rendezvous hashing is appropriate when:

  • nodes change over time
  • key movement should be minimal
  • implementation simplicity matters
  • each client can know the node list
  • weighted node assignment may be needed

It is common in distributed caches, sharded storage, request routing, and replicated systems.

Implementation

import hashlib

def score(node, key):
    data = f"{node}:{key}".encode()
    digest = hashlib.blake2b(data, digest_size=8).digest()
    return int.from_bytes(digest, "big")

def rendezvous_lookup(nodes, key):
    best_node = None
    best_score = -1

    for node in nodes:
        s = score(node, key)
        if s > best_score:
            best_score = s
            best_node = node

    return best_node
import (
	"encoding/binary"
	"hash/fnv"
)

func rendezvousScore(node string, key string) uint64 {
	h := fnv.New64a()
	h.Write([]byte(node))
	h.Write([]byte{0})
	h.Write([]byte(key))
	return binary.BigEndian.Uint64(h.Sum(nil))
}

func RendezvousLookup(nodes []string, key string) string {
	bestNode := ""
	var bestScore uint64

	for i, node := range nodes {
		score := rendezvousScore(node, key)
		if i == 0 || score > bestScore {
			bestScore = score
			bestNode = node
		}
	}

	return bestNode
}