Scaling the cache: hash slots, hash tags and moving slots
The name picks the slot, the slot picks the primary: one call's keys share a slot, and clients follow MOVED and ASK.
Predict first
Before you read: predict
ExamHall's Redis Cluster has three primaries. At the start of an exam, a Lua script reads two keys in one call: exam:ECON-201:paper and exam:ECON-201:roster. Both keys live on the same primary.
What does the call return?
The 30-second version
Redis Cluster hashes each key's name into one of 16,384 slots, and each primary owns ranges of slots. A command that touches several keys needs them all in one slot, not just on one primary; a hash tag {…} makes only that part count. While a slot moves, keys the source does not hold answer ASK; afterwards, MOVED.
The name picks the slot, the slot picks the primary: one call's keys share a slot, and clients follow MOVED and ASK.
How it works
Step 1 of 12
In the kitchen
- the folder number comes from the serial's checksum, never from which centre has room → a key's slot (step 1)
Analogy: An ocean-float programme's data centres
Drifting floats radio in their readings. Each float's reports go in one of 16,384 numbered folders, the number worked out from the float's serial by a fixed checksum. Three data centres each keep blocks of folder numbers.
| In the programme | In Redis Cluster |
|---|---|
| the folder number comes from the serial's checksum, never from which centre has room | a key's slot (step 1) |
| the directory says which centre keeps which folder block | the slot map (step 2) |
| a cross-check pulls one folder per request; two folders in the same centre still mean two requests | one slot per call (step 4) |
a mission code in braces in the serial, AX{LAB-26}07: only the code is checksummed, so the mission shares one folder |
a hash tag (steps 5–6) |
| the biggest mission under one code keeps one centre busy with all of its work | a tag is a pin (step 7) |
| "folder block 4,000 is kept at centre C now: change your directory" | MOVED (steps 8, 12) |
| mid-transfer, for a report already shipped: "ask centre C for this one; your directory stands" | ASK (steps 10–11) |
In real terms: before naming keys for a cluster, list the calls that touch several keys; give exactly those keys a shared tag, and nothing else.
Breaks down when: a centre splits an overfull folder in two; a Redis slot is never split, so a tag shared by too many keys stays one slot.
Examples, run for real
4.1 ExamHall: one tag for the exam's start script
EXH-5100: ExamHall's start-of-exam Lua script reads an exam's paper and roster in one call. MR !5400 names them {exam:ECON-201}:paper and {exam:ECON-201}:roster, and every other exam's keys the same way.
4.1 EXH-5100 Redis 7.4.11 · {exam:ECON-201}:paper slot 2567 · {exam:ECON-201}:roster slot 2567 · primary 1 (slots 0-5460)
4.1 MR !5400 the start-of-exam Lua script reads both in one call: ["paper-v3","roster-212"]
4.1 12 exams' start scripts, 500 calls each: calls per primary 1500 / 1500 / 3000 · each exam on one primary: ECON-201 1, HIST-104 3, MATH-110 2, CHEM-150 2, BIO-120 3, PHYS-130 2, LAW-210 1, ART-101 3, GEO-140 3, CS-220 3, MED-301 1, PSY-115 3
The two names share a slot, so one call reads both (steps 5 and 4). Each exam's keys stay on one primary (step 7); for ECON-201's paper, read by every candidate, ExamHall adds a short in-process copy on each of its 6 instances, the fix cache-hot-keys-and-sizing teaches.
4.2 Payments ledger: one slot, moved key by key
An account's two keys share slot 10838. The operator moves the slot to another primary, copying the entries first.
4.2 ledger slot 10838 ({acct:58}) moves from primary 2 to primary 3
4.2 mid-move, {acct:58}:balance not yet copied: GET on primary 2 -> 9200
4.2 mid-move, {acct:58}:entries already copied: LRANGE on primary 2 -> ASK 10838 (primary 3)
4.2 the same on primary 3 without ASKING -> MOVED 10838 (primary 2)
4.2 on primary 3 after ASKING -> OK then e1
4.2 move finished: GET {acct:58}:balance on primary 2 -> MOVED 10838 (primary 3)
Mid-move, the source served the key it still held and sent the moved one on with ASK; the target served it only after ASKING (steps 9–11). Once the move ended, the source answered MOVED (step 12).
Try it
Answer first, then check. Nothing is saved.
Question 1 of 6
A payments ledger runs on a Redis Cluster with three primaries. Account 7's keys are named {acct:7}:balance, {}{acct:7}:entries, {acct:7}:{limits}, holds:{}:{acct:7} and {{acct:7}}:fees.
How many different hash slots do these five keys fall in?
Question 2 of 6
A ledger service's Redis Cluster has three primaries, A, B and C, and the {acct:31} and {acct:45} keys both live on A. A service instance uses ioredis, a Redis Cluster client, and holds the slot map it loaded before either move below. An operator has finished moving the slot of the {acct:31} keys from A to B. The instance reads {acct:31}:balance, then {acct:31}:limit. The operator then moves the slot of the {acct:45} keys from A to C, and that move also finishes. The instance then reads {acct:45}:balance, {acct:45}:limit and {acct:31}:balance.
How many of the five reads are redirected?
Question 3 of 6
A payments ledger keeps 40,000 entry keys on a Redis Cluster with three primaries, about 13,300 on each. The team adds a fourth, empty primary and runs redis-cli --cluster reshard once: it moves 2,000 slots from the first primary to the new one.
About how many keys move?
Question 4 of 6
A ledger's Redis Cluster is moving the slot of account 9's keys from primary A to primary B. Account 9 has 50 keys, {acct:9}:e:0 to {acct:9}:e:49, and so far 30 of them have been copied to B and deleted from A. A service instance now uses ioredis, a Redis Cluster client, to write once to each of the 50 keys, then to create 10 new keys, {acct:9}:hold:0 to {acct:9}:hold:9.
Afterwards, how many of account 9's keys does B hold?
Question 5 of 6
A chat service keeps room 812's last 100 messages as keys {room:812}:msg:0 to {room:812}:msg:99, all in one slot of a three-primary Redis Cluster. An operator is moving that slot from primary A to primary B; so far 60 of the 100 keys have been copied to B and deleted from A. The interviewer asks what the move costs B meanwhile: a service instance reads all 100 keys once through ioredis, a Redis Cluster client.
How many commands does the instance send to B for these reads?
Question 6 of 6
A streaming service keeps, for each of 3,000 viewers, a resume position and a "continue watching" list on a Redis Cluster with three primaries. One Lua script updates a viewer's position and list together. Goal: the script runs for every viewer, and no primary holds more than 40% of the keys.
Which naming meets the goal?
Go deeper
Pro tips
- Ask the server for a name's slot.
CLUSTER KEYSLOT <name>returns the slot the server will use, including its brace rules. When: you design key names with tags, or a key keeps being redirected (steps 5–6). - Tag only what one call needs together. The specification says hash tags exist "to ensure that multiple keys are allocated in the same hash slot"; a tag on a whole tenant puts all of it on one primary. When: a key family grows with users, such as one entry per viewer (step 7).
Source
- Redis docs, Redis cluster specification (source
content/operate/oss_and_stack/reference/cluster-spec.md, redis/docs branch main): https://redis.io/docs/latest/operate/oss_and_stack/reference/cluster-spec/ · fetched 2026-10-18. "HASH_SLOT = CRC16(key) mod 16384"; "Each master node in a cluster handles a subset of the 16384 hash slots" (steps 1–2); "Commands performing complex multi-key operations like set unions and intersections are implemented for cases where all of the keys involved in the operation hash to the same slot" (step 4); "only what is between the first occurrence of{and the following first occurrence of}is hashed"; "if the key starts with{}, it is guaranteed to be hashed as a whole" (steps 5–6); "The client is not required to, but should try to memorize that hash slot 3999 is served by 127.0.0.1:6381" (step 8); "When a slot is set as MIGRATING, the node will accept all queries that are about this hash slot, but only if the key in question exists, otherwise the query is forwarded using a-ASKredirection" (step 10); "ASK means to send only the next query to the specified node"; "Don't yet update local client tables to map hash slot 8 to B" (step 11); "Once hash slot 8 migration is completed, A will send a MOVED message" (step 12). The page also describes Redis 8 features; every quoted rule was also run on Redis 7.4.11. Valid as of 2026-10-18. - Redis docs, Client-side caching reference (source
content/develop/reference/client-side-caching.md, redis/docs branch main): https://redis.io/docs/latest/develop/reference/client-side-caching/ · fetched 2026-10-18. Named by the curriculum row for the running case's in-process copy; that copy is taught bycache-hot-keys-and-sizing, so this lesson quotes nothing from it and no key rests on it. Valid as of 2026-10-18.
Related lessons
Checked against the tools and docs as of 2026-10-18.