Consistent Hashing: The 1997 Paper Quietly Running the Internet
Dynamo, Cassandra, and every major CDN route requests through an idea from a 1997 theory paper. Almost nobody using it has actually read why it works.
Consistent hashing shows up in almost every distributed system built in the last two decades, usually as a single line in an architecture diagram labeled “the ring.” Few engineers who rely on it have opened the paper that introduced it, a 1997 Symposium on Theory of Computing paper by David Karger, Eric Lehman, Tom Leighton, Matthew Levine, Daniel Lewin, and Rina Panigrahy. It was written to solve web cache hot spots, not databases. What it produced turned out to be one of the most reused ideas in distributed systems history.
The Problem With Ordinary Hashing
The obvious way to spread keys across a set of servers is to hash each key and take the result modulo the number of servers. It is simple and it balances load evenly, right up until the number of servers changes. Add or remove a single server from a pool of ten, and the modulo operation reassigns almost every key to a different server, because the divisor itself changed. For a cache, that means a near-total wipeout the moment you scale up or down. For a database, it means moving almost the entire dataset across the network just to add one machine.
The Karger paper frames this precisely: a good hash function for a distributed system should change “minimally” as the range of the function changes, meaning as servers come and go. Ordinary modulo hashing fails that test almost completely.
How the Ring Actually Works
Consistent hashing solves this by hashing servers and keys into the same circular space, typically visualized as a ring of hash values from 0 up to some large maximum and back to 0. Each server is placed on the ring at the point given by hashing its identifier. Each key is placed the same way, and it belongs to the first server found walking clockwise from the key’s position. That single rule is the entire mechanism.
When a server is removed, only the keys that were mapped to it need to move, and they move to the very next server clockwise on the ring. Every other key on the ring is completely undisturbed, because its nearest clockwise server never changed. The same logic applies in reverse when a server is added: it only steals keys from its immediate clockwise neighbor. This is the entire reason the scheme works, and it is a direct geometric consequence of using a circle instead of a modulo operation.
One wrinkle shows up quickly in practice. Placing each physical server at a single random point on the ring produces very uneven slices, since the gaps between random points on a circle are far from equal. The fix, used by every production implementation, is virtual nodes: each physical server is hashed into many points on the ring instead of one, so its total share of the circle averages out close to its fair portion.
import hashlib
import bisect
class ConsistentHashRing:
def __init__(self, nodes, virtual_nodes=100):
self.ring = []
self.ring_map = {}
for node in nodes:
for v in range(virtual_nodes):
point = self._hash(f"{node}-{v}")
self.ring.append(point)
self.ring_map[point] = node
self.ring.sort()
def _hash(self, key):
return int(hashlib.md5(key.encode()).hexdigest(), 16)
def get_node(self, key):
point = self._hash(key)
idx = bisect.bisect(self.ring, point) % len(self.ring)
return self.ring_map[self.ring[idx]]
ring = ConsistentHashRing(["node-a", "node-b", "node-c"])
print(ring.get_node("user:1024"))
print(ring.get_node("user:2048"))
Save this as ring.py and run it with python3 ring.py, no dependencies required. It prints which node owns each key. This is the core of the mechanism; production systems add replication, failure handling, and consistency protocols on top of it, but the placement rule itself is exactly this.
What the Numbers Actually Show
To see the difference for real rather than take it on faith, the comparison below simulates 10,000 keys distributed across ten servers, then adds an eleventh server and counts how many keys had to move under each scheme.

That is the entire value proposition in one chart. Modulo hashing rebuilds almost the whole mapping on every membership change. Consistent hashing moves only the keys that logically have to move, a number that scales with 1 divided by the new node count rather than with the total number of keys.
Virtual nodes matter just as much once the ring is built. Placing each server at a single ring position produces wildly uneven load, in this same simulation one node ended up with zero keys out of ten thousand while another absorbed over a quarter of them. Spreading each server across 100 virtual points brings every node much closer to its fair share.

From a Web Caching Paper to the Backbone of NoSQL
The path from theory paper to infrastructure staple ran through a company most engineers do not associate with it. Two of the paper’s co-authors, Daniel Lewin and Tom Leighton, founded Akamai in 1998, directly out of this research, and consistent hashing became part of how Akamai balances load within a cluster of edge servers to this day.
The idea reached mainstream distributed databases in 2007, when Amazon’s Dynamo paper named consistent hashing as its core partitioning technique, explicitly adding the virtual node refinement to smooth out load imbalances. Dynamo’s design in turn shaped Cassandra, which was open-sourced by Facebook the following year and still uses a consistent hash ring, now usually with a dedicated partitioner, to decide which nodes own which rows. From there the same idea spread into load balancers and CDN request routing wherever a set of backend servers needs to grow or shrink without reshuffling everything each time.
| System | Where consistent hashing shows up |
|---|---|
| Akamai CDN | Balances load within a cluster of edge caching servers |
| Amazon Dynamo | Core mechanism for partitioning keys across storage nodes, with virtual nodes |
| Apache Cassandra | Token ring partitioning determines which nodes own which data ranges |
| General CDN / load balancer routing | Maps client requests to a changing pool of cache or backend servers |
Why this still matters if you never touch the ring directly:
- Understanding the mechanism explains why adding a node to a Cassandra cluster is a background operation instead of an outage
- It explains why cache hit rates barely dip when a caching tier scales, instead of collapsing entirely
- It clarifies why virtual node counts are a real tuning knob, not an arbitrary configuration default
- It is one of the few pieces of distributed systems theory you can verify yourself in about thirty lines of code
What We Have Learned
Consistent hashing earns its place in nearly every distributed system’s foundation for a narrow, well-defined reason: placing servers and keys on the same ring turns “which server owns this key” into a local geometric question instead of a global recomputation. That single property, keys only move when their immediate neighbor on the ring changes, is what lets Dynamo, Cassandra, and CDNs add or remove capacity without rebuilding their entire key space. The 1997 paper that proved this was solving a much smaller problem, web cache hot spots, but the underlying mathematics generalized far beyond what its authors were originally chasing, and two of them ended up building a company on it before Amazon or Facebook ever wrote a line of the systems that made it famous.


