Chapter 21 · Redis Cluster: Hash Slots, Routing, Resharding, and Cluster Availability
Hash Tags and Multi-Key Operations: Co-Locating Related Keys Without Creating Hot Slots
Design hash tags for intentional multi-key locality without collapsing the workload into one hot slot.
Learning outcomes
By the end of this lesson, you should be able to:
Design hash tags that co-locate only keys that genuinely require one multi-key atomicity/locality boundary.
Prove same-slot and cross-slot behavior with
CLUSTER KEYSLOT and deliberate
CROSSSLOT failures.
Explain why transactions, Lua scripts, and Redis Functions do not become cross-slot transactions in Cluster.
Recognize hot-slot risk created by over-broad tags and measure it with Redis 8.2+ slot statistics.
Choose between co-location, application decomposition, and an external consistency boundary.
Redis Open Source 8.10.1 using
redis:8.10.1; seven named containers are defined
but the normal cluster starts six nodes (three primaries + three
replicas) on private Docker network
atlasmart-redis-ch21-net; the seventh node is
started only for add/remove exercises; Redis Cluster uses
logical database 0 only; AOF everysec;
maxmemory 0/noeviction for this
bounded lab; TLS is off only because all Cluster client/bus
traffic is confined to one private single-host Docker network;
default ACL user is disabled; named
academy-admin and atlasmart-app users
use disposable lab passwords. No
Search/JSON/vector/time-series/probabilistic feature is
required. All keys use atlasmart:ch21:*.
1. Practical problem: AtlasMart cart checkout needs several keys together
Suppose one cart operation must read cart metadata, mutate cart lines, and update a cart-local dedupe marker atomically. Redis Cluster can execute a multi-key command/transaction/script only when every accessed key belongs to the same slot. Hash tags give the application a deliberate co-location boundary.
2. Same tag, same slot
Only the substring inside the first valid non-empty brace pair
participates in slot hashing. Keys
atlasmart:ch21:cart:{c42}:meta and
atlasmart:ch21:cart:{c42}:lines therefore share a
slot even though their full names differ.
for k in 'atlasmart:ch21:cart:{c42}:meta' 'atlasmart:ch21:cart:{c42}:lines' 'atlasmart:ch21:cart:{c42}:dedupe'; do docker exec -e REDISCLI_AUTH=AtlasMart-Ch21-Admin-Lab-Only-2026 atlasmart-redis-ch21-n1 redis-cli --user academy-admin CLUSTER KEYSLOT "$k"done
3. CROSSSLOT is a correctness error, not a transient retry
Two keys with different tags normally map to different slots. A
multi-key operation that spans those slots is rejected with
CROSSSLOT Keys in request don't hash to the same slot. Retrying the same command against a different node cannot
repair it because the data model itself violates Cluster
locality.
# Wrong: different cart tags.docker exec -e REDISCLI_AUTH=AtlasMart-Ch21-Admin-Lab-Only-2026 atlasmart-redis-ch21-n1 redis-cli -c --user academy-admin \ MGET 'atlasmart:ch21:cart:{c42}:meta' 'atlasmart:ch21:cart:{c99}:meta'# Repair: same cart boundary.docker exec -e REDISCLI_AUTH=AtlasMart-Ch21-Admin-Lab-Only-2026 atlasmart-redis-ch21-n1 redis-cli -c --user academy-admin \ MSET 'atlasmart:ch21:cart:{c42}:meta' open 'atlasmart:ch21:cart:{c42}:lines' 3docker exec -e REDISCLI_AUTH=AtlasMart-Ch21-Admin-Lab-Only-2026 atlasmart-redis-ch21-n1 redis-cli -c --user academy-admin \ MGET 'atlasmart:ch21:cart:{c42}:meta' 'atlasmart:ch21:cart:{c42}:lines'
4. Transactions/scripts/functions inherit the same slot boundary
MULTI/EXEC, Lua scripts, and Redis Functions can be
atomic server-side only where their keys are routable to one
Cluster node. A hash tag can make those keys co-located; it does
not create a distributed transaction coordinator across slots.
Dynamic/hidden key access in scripts also breaks client routing
because the client cannot route what it was not told.
5. The dangerous over-repair: tag everything to one tenant
A tempting answer is to tag every key with
{atlasmart} or one giant tenant ID. That eliminates
CROSSSLOT errors by putting almost everything into one slot—also
eliminating horizontal distribution. One slot then becomes a
memory, CPU, network, and failover hotspot regardless of how
many primaries exist.
6. Measure slot skew, not just key count
Redis 8.2+ CLUSTER SLOT-STATS can rank slots by key
count, CPU, network and, in current versions, memory. Create a
bounded skewed fixture, then compare the intentionally tagged
hot slot with distributed keys.
from redis.cluster import RedisClusterrc=RedisCluster(host="atlasmart-redis-ch21-n1",port=6379,username="atlasmart-app",password="AtlasMart-Ch21-App-Lab-Only-2026",decode_responses=True)for i in range(500): rc.set(f"atlasmart:ch21:l3:hot:{{campaign-1}}:{i}", "x"*128) rc.set(f"atlasmart:ch21:l3:spread:{i}", "x"*128)rc.close()
docker exec -e REDISCLI_AUTH=AtlasMart-Ch21-Admin-Lab-Only-2026 atlasmart-redis-ch21-n1 redis-cli --user academy-admin CLUSTER SLOT-STATS ORDERBY KEY-COUNT LIMIT 10 DESCdocker exec -e REDISCLI_AUTH=AtlasMart-Ch21-Admin-Lab-Only-2026 atlasmart-redis-ch21-n1 redis-cli --user academy-admin CLUSTER SLOT-STATS ORDERBY MEMORY-BYTES LIMIT 10 DESC
7. Design patterns for locality
Useful tag boundaries are often an entity or bounded aggregate whose operations naturally need one atomic node: one cart, one reservation, one rate-limit subject, or one order workflow state. Global reports, cross-customer rankings, or arbitrary joins usually should not be forced into one tag simply to reuse a multi-key command.
8. Hash-tag braces are part of key design/versioning
Changing tags later moves keys to different slots and can break scripts/transactions unless migrations are coordinated. Treat key-format/tag rules as a versioned application schema. Document the tag owner, expected cardinality per tag, worst-case hotness, and which multi-key operations depend on it.
9. Cluster-aware client behavior for multi-key commands
A client must determine all keys for the command and verify one
slot before routing. Some clients split certain operations into
per-node calls as a convenience, but that changes atomicity and
return/error semantics. Do not assume a client-side “multi-get
across cluster” has the server-side semantics of one Redis
MGET.
Check your understanding
- Why do two keys with {c42} share a slot?
- Can a hash tag create a cross-slot ACID transaction?
- Why is one global hash tag dangerous?
- What should you measure before choosing a tag?
Review the answers
Redis hashes the tag c42 rather than each whole key.
No. It co-locates selected keys on one slot/node; Redis Cluster still has no general cross-slot transaction coordinator.
It can concentrate most traffic/data in one slot and defeat horizontal sharding.
Per-tag cardinality, memory, CPU/request skew, multi-key need, failure impact, and likely growth.
10. Production judgment and bridge
Use tags sparingly where one-node atomicity materially simplifies correctness. Prefer natural distribution for unrelated keys. Monitor hot-slot statistics and version the key schema. Lesson 4 takes the next operational step: adding capacity, moving slots, removing nodes, and failing over primaries without spending the cluster’s safety headroom.
Summary and next step
Hash Tags and Multi-Key Operations: Co-Locating Related Keys Without Creating Hot Slots is now connected to observable Redis behavior, bounded failure cases, and production tradeoffs. Keep the evidence and cleanup state from this lesson; next, continue with Add/Remove Nodes, Reshard Slots, Migrate Keys, Fail Over Primaries, and Maintain Headroom.
Authoritative references
- Redis Cluster specification
- Scale with Redis Cluster
- CLUSTER SHARDS
- CLUSTER SLOTS — deprecated since 7.0
- CLUSTER INFO
- CLUSTER NODES
- CLUSTER KEYSLOT
- CLUSTER SETSLOT
- CLUSTER MIGRATION
- CLUSTER SLOT-STATS
- CLUSTER FAILOVER
- ASKING
- MIGRATE
- Redis 8.10 release notes
- Redis 8.10 — what is new
- redis-py — connect to Redis Cluster
- redis-py 8.1.0 cluster documentation