Consistent Hashing
What problem it solves, how the ring actually works, and how far to take it in an interview.
Contents
Consistent hashing is a foundational algorithm in distributed systems for spreading data across a cluster of servers. Its whole reason to exist is one specific pain: when the number of servers changes, ordinary hashing forces you to move almost all of your data. The best way to understand it is to build up from a motivating example and watch each problem appear.
01The problem: sharding a growing system
Imagine you’re designing a ticketing system like TicketMaster. At the start it’s simple: one database holds all event data, clients make requests to fetch event information, and everything works smoothly.
Success brings load. As the platform hosts more events, a single database can no longer keep up, so you distribute the data across multiple databases — a process called sharding. That immediately raises the question everything else hangs on:
Given an event, how do we know which database instance it lives on? With three databases, is a given event on 0, 1, or 2? We can’t query all of them on every request just because we don’t know where the data sits.
The point of a lookup rule is to avoid a fan-out. We want to compute the location of an event directly from its ID, not broadcast every read to every shard and hope one answers.
02First attempt: simple modulo hashing
The most straightforward way to place data across databases is modulo hashing:
- Take the event ID and run it through a hash function, turning it into a number.
- Take that number modulo the number of databases (
%). - The result tells you which database stores that event.
# any hash function works here — md5, murmur, etc. database_id = hash(event_id) % number_of_databases
With three databases:
hash(1234) % 3 = 1 → Database 1 hash(5678) % 3 = 0 → Database 0 hash(9012) % 3 = 2 → Database 2
Event #1234 hashed gives the large number 67211. Then 67211 % 3 = 2, so the event is stored on Database 2. The hash turns an arbitrary ID into a number; the modulo folds that number down into a valid database index.
This works great — until the cluster changes size.
Problem 1 · Adding a database remaps almost everything
To add a fourth database you naively switch the code to modulo 4:
database_id = hash(event_id) % 4
You push to production and database activity goes through the roof — and not just on the new instance, on all of them. Changing the divisor didn’t only affect data destined for the new node; it changed where almost every event maps.
Event #1234 mapped to Database 1 under % 3. Under % 4 it now computes to Database 0, so the data must physically move from DB1 to DB0. And #1234 isn’t special — most events land on a different node than before.
The result is a mass redistribution across all instances: a huge spike in database load, users unable to reach data or seeing slow responses.
Problem 2 · Removing a database does the same thing
Now suppose a database goes down — hardware failure, a bug, anything. You remove it from the pool and redistribute its data over the survivors. But the divisor changes from % 3 to % 2, and you hit the exact same redistribution problem: data that had no reason to move gets shuffled anyway.
In the video’s three-database version, event #1234 sat on Database 2. Decommission one node so the divisor changes, and #1234 — which in principle had no business moving — ends up on Database 1. The lesson: with modulo hashing, the identity of a key’s node is tied to the total count of nodes, so any change to the count reshuffles the world.
The defect isn’t the hash function — it’s the % N. Because N is baked into every mapping, changing N changes nearly every mapping. Consistent hashing exists to break that coupling.
03Consistent hashing: the hash ring
Consistent hashing is a technique that minimizes data redistribution when a node is added to or removed from a distributed system. The key insight: arrange both the data and the databases in a circular key space, called a hash ring.
The mechanism is three steps:
- Create a hash ring with a fixed number of points. To keep it simple, say 0–100.
- Place the database nodes on the ring. With four databases you might place them at 0, 25, 50, and 75.
- To locate an event, hash its ID as before — but instead of taking a modulo, find that value on the ring and walk clockwise until you hit a database. That’s where it lives.
A key belongs to the first node encountered while moving clockwise from the key’s hashed position on the ring.
In reality the ring spans 0 to 2³² − 1 — basically the full 32-bit integer space — not 0–100. The concept is identical; the small range just makes it easy to draw.
The ring isn’t a physical thing. It’s a mathematical construct programmed into your code — a way of interpreting hash values as positions on a circle. Nothing is literally arranged in a circle in memory.
Adding a database (DB5)
Add a fifth database at position 90. Now:
- Only events hashing to the range 75–90 need to move.
- Those events were previously walking clockwise to DB1 (at 0).
- Every other event stays exactly where it was.
Where modulo forced almost all data to move, here you relocate only about 60% of DB1’s events (the 15-unit slice from 75–90 out of DB1’s 25-unit span) — roughly 15% of all events. There is no mass redistribution.
Removing a database
If DB2 (at position 25) fails:
- Only events that mapped to DB2 need to move.
- They now walk clockwise to DB3 (at position 50).
- Everything else stays put.
A key’s owner depends only on the positions of nearby nodes, not on the total node count. Adding or removing a node changes ownership only for keys in that node’s arc — so movement is bounded to a small neighborhood instead of the whole ring.
04Virtual nodes
One problem remains. When DB2 failed above, all of its events landed on its single clockwise neighbor, DB3. Now DB3 carries 2× the load of DB1 and DB4. We’d prefer the departed node’s load to spread evenly rather than dump onto one neighbor.
Virtual nodes. Instead of placing each database at a single point, place it at many points on the ring by hashing several variations of its name — "DB1-vn1", "DB1-vn2", "DB1-vn3", and so on. Each physical database ends up scattered across the ring, and all the databases’ virtual nodes naturally intermix.
For example, instead of only hashing "DB1" to position 0, you hash its variants to positions like 20, 35, 65. Do this for every database and the ring becomes a fine-grained mix of small arcs owned by different physical nodes.
Say DB1’s virtual nodes sit at 0, 20, 40, 60, 80 and DB2’s at 5, 25, 45, 65, 85, with the others interleaved. When DB2 is removed, its arcs don’t all fall to one place. Walking clockwise, the freed ranges split across several survivors — e.g. 0–10 → DB3, 10–15 → DB4, 15–20 → DB1, 20–25 → DB3. The departed load ends up spread far more evenly than dumping everything on a single neighbor.
The more virtual nodes per database, the smoother the distribution. And it helps on the way in, too:
Without virtual nodes, a new node only takes load from its single clockwise neighbor. With virtual nodes, its positions are spread around the ring, so it absorbs a small slice from many existing nodes — a balanced cluster from the start, not just one relieved neighbor.
If you picture the virtual nodes as keeping the same order around the ring (DB1, DB2, DB3, …), it looks like DB2’s load would still always fall to DB3 — defeating the purpose. It doesn’t, because virtual node positions are not ordered; they’re scattered by hashing, so DB2’s neighbors vary all around the ring. Readers flagged that the original diagram implied a fixed order, and the author acknowledged it as a diagram bug rather than how the algorithm behaves.
You don’t need multiple hash functions. Real systems (Cassandra, DynamoDB, memcached) typically use a single hash function and derive each virtual node’s position from a combined key — roughly hash(physical_node_id + virtual_node_id). Different suffixes yield different, well-spread positions.
05Addressing hot spots
Even with virtual nodes distributing data evenly, hot spots can still occur.
A hot spot is when one node gets disproportionate traffic because certain keys are far more popular than others. Think of a ticketing system where a Taylor Swift concert generates 100× the reads of any other event.
Consistent hashing distributes keys evenly, not traffic. So it does nothing about hot spots on its own. Virtual nodes prevent structural imbalance (uneven key distribution); replication and salting prevent workload imbalance (uneven traffic). This is exactly the distinction to draw in an interview.
Strategies real systems use:
| Strategy | How it works | Notes |
|---|---|---|
| Read replicas | Replicate popular keys across multiple nodes and load-balance reads among them. | The most common approach. |
| Key-space salting | Append a random suffix to hot keys (e.g. taylor-swift-{0..9}) so they hash to different nodes; reads scatter across those nodes and get aggregated. | Spreads a single hot key over many nodes. |
| Adaptive rebalancing | Monitor traffic in real time and move specific key ranges off overloaded nodes. | Operationally complex; DynamoDB does this automatically. |
Commenters debated exactly when key-space salting helps, since scattering a key raises read fan-out (you must query all salted variants and aggregate). The leaning in discussion was that salting fits write-heavy hot keys — spread writes across nodes, aggregate on read (e.g. a like-count on a celebrity’s post) — and that it raises correctness questions the article doesn’t fully resolve. Treat the precise read-vs-write benefit as not settled by the source.
06Data movement in practice
Consistent hashing tells you where data should live — it doesn’t teleport terabytes when a node dies. In practice, most distributed databases pair consistent hashing with replication so failures need no data movement at all.
- DynamoDB replicates each partition across three availability zones. When a primary fails, a replica is promoted via a consensus algorithm like Raft — no data moves.
- Cassandra works similarly, replicating data to N consecutive nodes on the ring so reads can be served from surviving replicas.
Real data movement happens only during planned membership changes — adding capacity, or permanently replacing a node to restore the replication factor. Even then, consistent hashing guarantees only a bounded fraction of keys must be re-replicated, never the whole dataset.
When a node fails, data is not automatically transferred. Consistent hashing only tells new requests where to go (the next node clockwise). Actually surviving the failure is a separate job: keep replicas and promote one when a node dies. Note too that consistent hashing itself isn’t the replication mechanism — replication is handled by separate protocols — though consistent hashing is used for load balancing across a set of servers.
07Consistent hashing in the real world
Although the example scaled a database, consistent hashing applies to any scenario where you distribute data across a cluster — databases, caches, message brokers, or even a pool of application servers.
- Apache Cassandra — distributes data across the ring.
- Amazon DynamoDB — uses it under the hood for partition placement.
- CDNs — decide which edge server should cache specific content.
Redis Cluster uses a fixed hash slot approach instead: it divides the key space into 16,384 slots via CRC16(key) mod 16384 and assigns slot ranges to nodes. It’s simpler to reason about but needs more coordination when rebalancing. Consistent hashing vs. fixed hash slots is a genuine design choice you might discuss in an interview.
08When to use it in an interview
Most modern distributed systems handle sharding and data distribution for you. When you design a system on DynamoDB or Cassandra, you usually just need to mention that these use consistent hashing (or a form of it) under the hood to scale. Most interviews stop there.
The one time you should describe the algorithm in detail is when designing a single scaled backend component from scratch:
- Design a distributed database
- Design a distributed cache
- Design a distributed message broker
In those deep infrastructure interviews, be ready to explain:
- Why consistent hashing beats modulo-based sharding for data distribution.
- How virtual nodes improve load balancing across the cluster.
- Strategies for handling node failures and additions.
- How hot spots arise and how to mitigate them (replication, key salting).
- The relationship between consistent hashing and replication for fault tolerance.
09The one loose end: “consistent hashing” is used loosely
Consistent hashing solved a deceptively simple problem: distribute data across servers while minimizing redistribution when the server count changes. The implementation gets intricate, but the core is elegant — arrange everything in a circle and walk clockwise.
As Martin Kleppmann notes in Designing Data-Intensive Applications, some systems that claim to use “consistent hashing” actually use variations like hash-based partitioning with fixed slot ranges. What matters is the principle — minimizing data movement during rebalancing — even when the exact implementation differs from the textbook ring.
10Active recall
Why does hash(key) % N break when you add or remove a node?
Because N is part of every mapping. Changing the number of nodes changes the divisor, which changes the result for almost every key — forcing a mass redistribution across all nodes, not just movement involving the added/removed node.
State the clockwise-walk rule and why it bounds data movement.
A key belongs to the first node found walking clockwise from the key’s hashed position on the ring. A key’s owner depends only on the positions of nearby nodes, not on the total node count — so adding or removing a node only reassigns keys in that node’s arc, leaving everything else in place.
Adding DB5 at position 90 (nodes at 0/25/50/75): what moves, and roughly how much?
Only events in the 75–90 range, which previously walked clockwise to DB1 at 0. That’s about 60% of DB1’s 25-unit span (a 15-unit slice) ≈ 15% of all events. Everything else stays put.
What problem do virtual nodes solve, and how?
They fix uneven load when a node leaves or joins. Instead of one point per database, each database is hashed to many points (DB1-vn1, DB1-vn2, …) that intermix around the ring. When a node fails, its arcs are scattered, so its load spreads across many survivors instead of dumping on one clockwise neighbor. More virtual nodes → smoother distribution.
Why doesn’t consistent hashing fix hot spots — and what does?
It distributes keys evenly, not traffic. A single very popular key still hammers one node. Fixes target the workload: read replicas for the hot key (most common), key-space salting to scatter it across nodes, or adaptive rebalancing. Distinction: virtual nodes → structural imbalance; replication/salting → workload imbalance.
When a node fails, is its data automatically moved? What actually keeps the system available?
No. Consistent hashing only redirects new requests to the next node clockwise. Availability comes from replication (e.g. DynamoDB across 3 AZs, Cassandra to N consecutive ring nodes); a replica is promoted (via a consensus algorithm like Raft) with no data movement. Bulk movement happens only for planned membership changes, and even then only a bounded fraction of keys.
In an interview, when do you go deep on consistent hashing vs. just name-drop it?
Name-drop it when using managed systems (DynamoDB, Cassandra) — mention they use it under the hood. Go deep only when designing a scaled backend component from scratch: a distributed database, cache, or message broker.
11Quick revision
The mental model in one line
Must remember
- Modulo’s flaw:
Nlives in every mapping, so changingNremaps almost everything. - Ring guarantee: add/remove a node → only keys in that node’s arc move (bounded, not global).
- Add DB5: only the arc between the new node and its clockwise-previous node moves (~15% of keys in the worked example).
- Virtual nodes: one server → many scattered ring points → even spread on both join and leave.
- Keys ≠ traffic: even key distribution doesn’t prevent hot spots.
- Failures: handled by replication + promotion, not by moving data.
Important distinctions
| Concept | Fixes |
|---|---|
| Virtual nodes | Structural imbalance — uneven key distribution |
| Replication / key salting | Workload imbalance — uneven traffic (hot spots) |
| Consistent hashing | Where data should live — not moving it on failure |
| Replication protocols | Surviving failures without data movement |
Systems to name
- Use it: Cassandra, DynamoDB (partition placement), CDNs (edge cache placement).
- Variation: Redis Cluster → fixed hash slots,
CRC16(key) mod 16384. - Caveat: the term is used loosely; the real principle is minimizing movement on rebalance (Kleppmann).