$npx -y skills add redis/agent-skills --skill redis-clusteringRedis Cluster and replication guidance covering hash tags for multi-key operations, avoiding CROSSSLOT errors, and reading from replicas to scale read-heavy workloads. Use when designing keys for a sharded Redis Cluster, debugging CROSSSLOT errors on MGET / SDIFF / pipelines, con
| 1 | # Redis Clustering |
| 2 | |
| 3 | Guidance for designing keys and routing reads in a sharded Redis Cluster (and in standalone primary/replica replication). Covers the two failure modes that bite most new cluster users: `CROSSSLOT` errors on multi-key operations, and overloading primaries with read traffic. |
| 4 | |
| 5 | ## When to apply |
| 6 | |
| 7 | - Designing keys for a Redis Cluster deployment. |
| 8 | - Debugging a `CROSSSLOT` error on `MGET`, `SDIFF`, transactions, or pipelines. |
| 9 | - Implementing transactions / Lua scripts that touch multiple keys. |
| 10 | - Scaling out read traffic without adding shards. |
| 11 | |
| 12 | ## 1. Hash tags for multi-key operations |
| 13 | |
| 14 | Redis Cluster distributes keys across 16,384 slots by hashing the key name. Any command that touches **multiple keys** (`MGET`, `SDIFF`, `SUNIONSTORE`, transactions, pipelines, Lua scripts with multiple `KEYS[]`) requires all keys to live on the **same slot** — otherwise the server returns a `CROSSSLOT` error. |
| 15 | |
| 16 | Hash tags force this: the part between `{` and `}` is the only thing hashed for slot assignment, so two keys sharing a hash tag always land together. |
| 17 | |
| 18 | ```python |
| 19 | # Same slot — multi-key ops work |
| 20 | redis.set("{user:1001}:profile", "...") |
| 21 | redis.set("{user:1001}:settings", "...") |
| 22 | redis.lmove("{user:1001}:pending", "{user:1001}:processed", "LEFT", "RIGHT") |
| 23 | ``` |
| 24 | |
| 25 | ```python |
| 26 | # Different keys, no hash tag — CROSSSLOT on multi-key commands in cluster mode |
| 27 | redis.set("user:1001:profile", "...") |
| 28 | redis.set("user:1001:settings", "...") |
| 29 | pipe = redis.pipeline() |
| 30 | pipe.get("user:1001:profile") |
| 31 | pipe.get("user:1001:settings") |
| 32 | pipe.execute() # CROSSSLOT error in cluster |
| 33 | ``` |
| 34 | |
| 35 | Rules of thumb: |
| 36 | |
| 37 | - **Use a tag scoped to the meaningful entity**, e.g. `{user:1001}`. Avoid bare `{1001}` — unrelated namespaces (`purchase:{1001}`, `employee:{1001}`) would all collide on the same slot. |
| 38 | - **Only tag where you actually need multi-key ops.** Tagging everything creates hotspots and defeats the point of sharding. |
| 39 | - A single-key command on a hash-tagged key works fine, so adding tags later is incremental — but renaming keys in production is painful, so plan tagging up front for entities you'll group. |
| 40 | |
| 41 | See [references/hash-tags.md](references/hash-tags.md). |
| 42 | |
| 43 | ## 2. Read replicas for read-heavy workloads |
| 44 | |
| 45 | If reads dominate writes, route them to replicas to free primary capacity. Works both in Redis Cluster (each shard has 1+ replica) and in standalone primary/replica replication. |
| 46 | |
| 47 | ```python |
| 48 | # Redis Cluster: enable replica reads on the client |
| 49 | from redis.cluster import RedisCluster |
| 50 | |
| 51 | rc = RedisCluster(host="localhost", port=6379, read_from_replicas=True) |
| 52 | rc.set("key", "value") # → primary |
| 53 | value = rc.get("key") # → may be served by a replica |
| 54 | ``` |
| 55 | |
| 56 | For non-cluster setups, point two clients at the right nodes: |
| 57 | |
| 58 | ```python |
| 59 | primary = Redis(host="primary-host", port=6379) |
| 60 | replica = Redis(host="replica-host", port=6379) |
| 61 | primary.set("key", "value") |
| 62 | value = replica.get("key") |
| 63 | ``` |
| 64 | |
| 65 | The trade-off is consistency: **replicas are eventually consistent**. Don't read your own writes from a replica; don't use replica reads for anything that requires strict freshness (financial balances, idempotency state). Good fits: cache layers, analytics, dashboards, recommendation feeds. |
| 66 | |
| 67 | See [references/read-replicas.md](references/read-replicas.md). |
| 68 | |
| 69 | ## References |
| 70 | |
| 71 | - [Redis Cluster spec — hash tags](https://redis.io/docs/latest/operate/oss_and_stack/reference/cluster-spec/#hash-tags) |
| 72 | - [Redis: multi-key operations in cluster](https://redis.io/docs/latest/operate/rs/databases/durability-ha/clustering/#multikey-operations) |
| 73 | - [Redis: Replication](https://redis.io/docs/latest/operate/oss_and_stack/management/replication/) |