Module A-9·12 min read

The 16,384 hash slot model, CRC16 key hashing, hash tags for co-locating keys on the same slot, MOVED vs ASK redirections, multi-key command constraints in Cluster, and cluster-enabled client configuration.

Written by Jatin Jain Saraf · Architect of SupraScan

A-9 — Redis Cluster: Hash Slots and Data Distribution

Who this module is for: Your Redis dataset has grown beyond what a single node can hold in RAM, or your write throughput exceeds what a single node can handle. Redis Cluster is the answer — but it introduces constraints around multi-key operations, key routing, and command support that you must understand before adopting it. This module covers the Cluster model end-to-end.


Why Cluster?

A single Redis node has two hard limits:

  1. RAM — the entire dataset must fit in one machine's memory. A 1TB dataset cannot fit on a 256GB node.
  2. Write throughput — all writes go through one single-threaded event loop. At some point, you hit the wall (~1M ops/sec on modern hardware).

Redis Cluster solves both by distributing data across multiple primary nodes, each responsible for a subset of the keyspace.


The Hash Slot Model

Redis Cluster partitions the keyspace into 16,384 hash slots (numbered 0–16383). Every key belongs to exactly one slot:

slot = CRC16(key) % 16384

Hash slots are assigned to primary nodes. A 3-node cluster might assign:

Node 1 (primary-1): slots 0–5460
Node 2 (primary-2): slots 5461–10922
Node 3 (primary-3): slots 10923–16383

When a client issues GET user:1001, Redis computes CRC16("user:1001") % 16384 = 7638. Slot 7638 belongs to Node 2. The client sends the GET to Node 2.


MOVED and ASK Redirections

Cluster clients must track which node owns which slots. When a client sends a command to the wrong node, the node responds with a MOVED redirection:

GET user:1001 → sent to Node 1 (wrong node)
Node 1 → -MOVED 7638 10.0.1.52:6379
          ↑ slot ↑ correct node address

The client updates its local slot-to-node map and resends the command to the correct node. A well-implemented Cluster client handles this automatically and transparently — application code does not see MOVED errors.

ASK redirections are similar but temporary — used during slot migration (when a slot is being moved from one node to another). ASK means "ask this specific node for this specific command, but do not update your slot map."

GET product:999 → slot being migrated
Node 1 → -ASK 12345 10.0.1.53:6379
 
Client: sends ASKING command to 10.0.1.53, then resends GET product:999
Note: ASKING is not stored; next request for slot 12345 still goes to Node 1
      until migration completes and a MOVED is issued

Hash Tags: Controlling Key Placement

Multi-key commands (MGET, MSET, pipelines, Lua scripts, transactions) require all keys to be on the same node. In Cluster mode, this means all keys must be in the same hash slot.

Hash tags force a specific portion of the key to be used for slot computation:

CRC16(key) % 16384   → uses the full key
 
# With hash tag {tag}: only the portion inside {} is hashed
CRC16(tag) % 16384
user:1001:profile  → CRC16("user:1001:profile") % 16384 = slot A
user:1001:session  → CRC16("user:1001:session") % 16384 = slot B (different!)
 
{user:1001}:profile → CRC16("user:1001") % 16384 = slot X
{user:1001}:session → CRC16("user:1001") % 16384 = slot X (same slot!)

With hash tags, all keys for a specific user share the same slot — enabling multi-key operations:

// Without hash tags: MGET fails in Cluster (keys on different slots)
redis.mget('user:1001:profile', 'user:1001:session')  // CROSSSLOT error
 
// With hash tags: MGET works (all keys on the same slot)
redis.mget('{user:1001}:profile', '{user:1001}:session')  // ✓

Design rule: For related keys that must be accessed together, use hash tags from the start. Retrofitting hash tags requires migrating all existing keys.


Multi-Key Command Constraints

Commands that operate on multiple keys fail in Cluster if the keys span different slots:

MGET key1 key2 key3    → CROSSSLOT error if keys are on different nodes
MSET key1 v key2 v     → CROSSSLOT error
RPOPLPUSH list1 list2  → CROSSSLOT error
SUNIONSTORE dest src1 src2  → CROSSSLOT error if different slots
Lua scripts via EVAL   → CROSSSLOT error if KEYS span different nodes
MULTI/EXEC transactions → keys must be on same slot

Workarounds:

  1. Hash tags — co-locate related keys on the same slot
  2. Application-side batching — split multi-key operations by slot, execute per-node, merge results in the application
  3. Single-key alternatives — replace MGET with a pipeline of GET commands (each routed to the correct node automatically by the Cluster client)
// Replace MGET with a pipeline in Cluster (each GET routed correctly)
const pipeline = redis.pipeline();
['user:1001', 'user:1002', 'user:1003'].forEach(key => pipeline.get(key));
const results = await pipeline.exec();

Sign in to keep reading

The rest of this module is free — sign in with Google to unlock it and track your progress.

Sign in & Register

Discussion

0

Join the discussion

Loading comments...

© 2026 Jatin Jain Saraf (JJS). All rights reserved.