← Back to list

Consistent Hashing: How Discord Scales to Billions of Users

This article was originally published on The Cypher Hub, my dedicated platform for engineering deep dives.

Tanyaradzwa T Mushonga · 2026-01-13 14:53 · 0 claps · 4.5 min read
#consistent-hashing #distributed-hash-table #database-partitioning #database-sharding #cache-stampede
Open on Medium ↗

Consistent Hashing: How Discord Scales to Billions of Users

This article was originally published on The Cypher Hub, my dedicated platform for engineering deep dives.

It is 2026. You have just launched “ZimChat,” a new messaging app for Zimbabwe.

In the first week, you have 1,000 users. You run everything on a single server called Server A. Life is simple. A user logs in, Server A handles the connection, and everyone is happy.

By month three, you have 1 million users. Server A is smoking. It’s hitting 100% CPU usage. You do what any engineer would do: you buy three more servers (Server B, Server C, Server D) and put a Load Balancer in front of them.

Now you have a new problem. When User 123 connects, which server should they go to?

If they go to Server B to store their session data, but the next request goes to Server C, Server C won't know who they are. You need a way to map specific users to specific servers deterministically.

You decide to use the simplest math trick in the book: Modulo Hashing.

And that is where your nightmare begins.

1. The Trap: Why Simple Hashing Fails

The naive approach to distributed systems — which I discuss often in my System Design Deconstructed series is using the modulo operator (%).

You hash the User ID to get a number, then divide by the number of servers (N) and take the remainder.

Server Index = hash (User ID) mod N

Let’s say you have 4 servers (N=4).

  • User “Tanya” (Hash=10) -> 10 mod 4 = 2. Goes to Server 2.
  • User “Farai” (Hash=13) -> 13 mod 4 = 1. Goes to Server 1.
  • User “Simba” (Hash=16) -> 16 mod 4 = 0. Goes to Server 0.

This works perfectly. The load is distributed evenly. The cache is warm.

The Disaster Scenario: The Cache Stampede

It’s Friday night. Traffic spikes. You need to add a 5th server to handle the load (N=5). Let’s re-calculate the routes:

  • User “Tanya” (Hash=10) -> 10 mod 5 = 0. Moved to Server 0.
  • User “Farai” (Hash=13) -> 13 mod 5 = 3. Moved to Server 3.
  • User “Simba” (Hash=16) -> 16 mod 5 = 1. Moved to Server 1.

Wait. Look at that. Almost every single user just got re-mapped to a different server.

In a distributed cache (like Redis) or a stateful system (like Discord Voice Channels), this is catastrophic. Because the mapping changed, Server 0 doesn’t have Tanya’s data. It has to fetch it from the database.

Multiply this by 10 million users. Suddenly, your database receives 10 million requests in one second because the cache just became useless. This is called the Cache Stampede (or Thundering Herd), and it will take your entire platform offline.

You effectively DDoS’d yourself just by adding hardware.

2. The Solution: Consistent Hashing

This is the exact problem Discord, Amazon DynamoDB, and Cassandra faced. They needed a way to add or remove servers without reshuffling the entire world.

Enter Consistent Hashing, a concept introduced by MIT researchers in 1997.

The Concept: The Infinite Ring

Imagine a circle (a ring). This ring represents all possible hash values, from 0 to 2^{32}-1 (a huge number). It’s essentially an infinite timeline wrapped into a circle.

Instead of just hashing users, we also hash the servers themselves. We map the servers onto the ring based on their IP addresses or names.

  • Server A maps to position 100 on the circle.
  • Server B maps to position 500.
  • Server C maps to position 900.

The Rule: “Walk Clockwise”

Now, when a user (Request) comes in, we hash their ID to place them on the ring.

  • User X maps to position 150.

To find which server handles User X, we don’t do any division. Instead, we simply move clockwise along the ring until we hit a server.

  • User X (150) -> walks clockwise -> passes empty space -> hits Server B (500).

Therefore, Server B is responsible for User X.

3. Why This Saves the Day

The magic of Consistent Hashing is stability.

Scenario A: Scaling Up (Adding a Node)

Let’s go back to our disaster scenario. We have Servers A (100), B (500), and C (900). User X (150) is on Server B.

Now, we add Server D at position 300.

  • User X (150) -> walks clockwise -> hits Server D (300).
  • User Y (600) -> walks clockwise -> hits Server C (900).

Analysis:

  • User X moved from Server B to Server D.
  • User Y stayed on Server C.

In fact, the only users who move are the ones who fall specifically between Server A and the new Server D. Everyone else on the ring stays exactly where they are. Mathematically, when you add a node to a cluster of $N$ nodes, only $1/N$ of the data needs to move.

Scenario B: Fault Tolerance (Node Death)

What happens if Server B (at 500) crashes?

In a modulo system, removing a server would reshuffle everyone. In a consistent hashing ring, if Server B disappears, the users destined for it simply "fall through" to the next server on the ring (Server C). The rest of the ring is unaffected.

4. The “Hotspot” Problem & Virtual Nodes

There is a flaw in the simple ring logic. What if Server A covers a tiny slice of the ring, while Server B covers a huge arc? Server B will get crushed by traffic.

Virtual Nodes (Vnodes)

To solve this, we don’t map Server A to just one point. We map it to 100 different points on the ring using multiple hash functions.

  • Server A exists at positions 100, 5000, 8000, 12000...
  • Server B exists at positions 200, 6000, 9000, 13000...

This achieves Uniform Distribution (no hotspots) and Weighted Balancing (powerful servers get more Vnodes).

5. Case Study: Discord

Discord is an interesting case because it is a massive stateful system. When you join a Voice Channel, you hold a persistent UDP connection to a specific voice server.

If Discord used Modulo Hashing, every time they autoscaled their voice fleet, millions of gamers would be disconnected. Instead, they use Consistent Hashing (specifically a variation called Ringpop) to manage these connections.

The Gossip Protocol

Servers use a Gossip Protocol to talk to each other (“Hey, Server D just joined!”). Information spreads like a virus through the cluster, updating the Hash Ring map on every node within seconds.

Conclusion

System Design is about predicting failure.

Modulo hashing assumes the world is static. Consistent hashing accepts that the world is chaotic — servers crash, scale, and lag. By decoupling data keys from physical server counts, Consistent Hashing allows giants like Discord and Netflix to scale infinitely.

Want to learn more about System Architecture?

I am writing a full series called System Design Deconstructed where I break down the architecture of:

👉 Read the full collection on The Cypher Hub


메타데이터
post_id
d1584c033a76
slug
consistent-hashing-how-discord-scales-to-billions-of-users-d1584c033a76
url
https://medium.com/@tanyaradzwatmushonga/consistent-hashing-how-discord-scales-to-billions-of-users-d1584c033a76
canonical_url
https://medium.com/@tanyaradzwatmushonga/consistent-hashing-how-discord-scales-to-billions-of-users-d1584c033a76
author_url
https://medium.com/@tanyaradzwatmushonga
status
ok
fetched_at
2026-06-22 17:31:34