What Is Redis Cluster?
Redis Cluster is the built-in sharding and high-availability mode of Redis. It splits the keyspace across multiple primary nodes, each owning a subset of 16,384 hash slots, and lets each primary have one or more replicas that can be promoted automatically when it fails.
The distinction from plain replication is what gets scaled. Replication copies the whole dataset to every replica, so it scales reads but never writes or memory — every node still has to hold everything. Cluster shards the dataset, so ten nodes hold roughly a tenth each and absorb roughly a tenth of the writes each. Cluster answers both "one machine is not big enough" and "one machine is not reliable enough"; if only the second applies, Sentinel is the simpler tool.
The price is a set of constraints that catch teams out after migration: no cross-slot multi-key operations, no SELECT, and pub/sub that behaves differently than it did on a single node. Those are covered below, because they are the part most introductions skip.
How Redis Cluster Shards Data: 16,384 Hash Slots
Redis Cluster does not hash keys directly to nodes. It hashes them to a fixed intermediate space of 16,384 hash slots, and then assigns ranges of slots to nodes:
HASH_SLOT = CRC16(key) mod 16384
The indirection is the whole design. Because slots are a stable, fixed-size space, moving data between nodes means reassigning slot ownership rather than rehashing the keyspace — so adding a node does not invalidate every key's location the way naive hash(key) % node_count would. It achieves the same goal as consistent hashing through a simpler mechanism, and it is why resharding can happen with the cluster online.
Why 16,384 and not 65,536? Redis creator Salvatore Sanfilippo has explained it as a trade-off in message size: every node broadcasts its slot ownership as a bitmap in cluster bus heartbeats, and 16,384 bits is 2 KB per message where 65,536 bits would be 8 KB — significant overhead on a protocol where every node gossips continuously. It also comfortably exceeds the practical cluster size, since 16,384 is the theoretical ceiling on primaries and the suggested maximum is on the order of 1,000 nodes.
Hash Tags: Forcing Keys Into the Same Slot
Because keys land wherever CRC16 sends them, two related keys usually live on different nodes. Any command touching both then fails:
> MSET user:42:profile "..." user:42:cart "..."
(error) CROSSSLOT Keys in request don't hash to the same slot
The fix is a hash tag. If the first { in a key is followed by a } with at least one character between them, Redis hashes only that substring instead of the whole key:
> MSET {user:42}:profile "..." {user:42}:cart "..."
OK
The exact rule is narrower than most people assume, and the edge cases bite:
| Key | What gets hashed | Why |
|---|---|---|
{user:42}:profile | user:42 | The normal case |
foo{bar}{zap} | bar | Only the first {…} counts |
foo{{bar}}zap | {bar | First { to first } — the inner brace is part of the tag |
foo{}{bar} | foo{}{bar} | The first pair is empty, so the algorithm gives up and hashes the whole key — it does not skip ahead to {bar} |
{}key | {}key | Guaranteed whole-key hashing |
The trap is over-tagging. A hash tag pins every key carrying it to one slot, and therefore to one node. Tag by tenant and one large tenant becomes a hot node that cannot be split — you have reintroduced the single-node ceiling that Cluster existed to remove. Tag at the smallest granularity your multi-key operations actually require, and no wider.
MOVED and ASK: How Clients Find the Right Node
Redis Cluster has no proxy. Any node will answer a request for a slot it owns and redirect one it does not, and the client is expected to learn the topology and route directly. There are two redirects, and conflating them is a common client bug.
-MOVED | -ASK | |
|---|---|---|
| Means | This slot now belongs to another node, permanently | This one key is not on this node; the slot is mid-migration |
| Client should | Update its cached slot map, then retry | Retry on the named node only for this request |
| Requires | Nothing | An ASKING command immediately before the retry |
| Slot map | Updated | Not updated |
The distinction exists because the legacy resharding path is not atomic — and it is still what redis-cli --cluster reshard drives today, so every client must implement it. While a slot migrates that way, some of its keys are on the source node and some on the destination. The source answers for keys it still holds and returns ASK for those it no longer has; the destination refuses requests for an importing slot unless prefixed with ASKING. That handshake is what stops clients from caching a half-migrated topology.
There is a third reply worth handling. A multi-key command inside one migrating slot — whose keys are split across source and destination, or which references a key that does not exist — returns -TRYAGAIN, meaning retry shortly rather than redirect anywhere. (Keys in different slots give CROSSSLOT instead; that is a permanent error, not a retryable one.) Clients implementing only MOVED and ASK surface -TRYAGAIN as a hard failure during resharding. Note that ASK, ASKING and -TRYAGAIN are artefacts of the key-by-key path specifically — under atomic slot migration they do not arise.
A production client should cache the slot map, refresh it on MOVED, and handle ASK without touching the cache. Clients that re-discover topology on every redirect work, but collapse under load during a reshard.
Building a Cluster: Minimum Topology
A working cluster wants at least three primaries — redis-cli --cluster create refuses to build one with fewer. Automatic failover requires a majority vote among surviving primaries, and below three the survivors can never form one. For production the recommendation is six nodes — three primaries, three replicas, since a primary without a replica has nothing to fail over to.
Each node needs two ports open: the client port, and the cluster bus port, by default client port + 10000 (6379 → 16379) unless overridden with cluster-port (Redis 7.0+), used for the binary gossip protocol. Blocking the bus port is a very common reason a cluster refuses to form.
# redis.conf
port 6379
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
With the nodes running, create the cluster in one command:
redis-cli --cluster create \
10.0.0.1:6379 10.0.0.2:6379 10.0.0.3:6379 \
10.0.0.4:6379 10.0.0.5:6379 10.0.0.6:6379 \
--cluster-replicas 1
This wraps what would otherwise be manual CLUSTER MEET to introduce the nodes and CLUSTER ADDSLOTS to divide the 16,384 slots between them. redis-cli --cluster check verifies full slot coverage afterwards, and CLUSTER NODES prints the topology as each node sees it — the first thing to read when nodes disagree.
Failover: PFAIL, FAIL and Replica Promotion
Failure detection is gossip-based and deliberately conservative, running through two states.
PFAIL (possible failure) is a local suspicion: one node has not heard from another for longer than cluster-node-timeout. It carries no authority on its own.
FAIL is cluster-wide. A node escalates PFAIL to FAIL once it has collected agreement from a majority of primaries within twice the node timeout, then broadcasts it so every node marks the target failed. Only then can that primary's replicas stand for election, and the replica with the most advanced replication offset is favoured.
The practical consequence is that recovery time is roughly cluster-node-timeout plus a second or two, not instantaneous. Lowering the timeout speeds recovery but makes spurious failovers likelier on a congested network — the same trade-off that governs split-brain risk generally. For planned work, CLUSTER FAILOVER on a replica performs a coordinated handover that waits for the replication stream to drain first, so no writes are lost.
Resharding and Slot Migration
Adding capacity means moving slots, which happens online:
redis-cli --cluster reshard 10.0.0.1:6379 \
--cluster-from <source-node-id> --cluster-to <target-node-id> \
--cluster-slots 1000 --cluster-yes
The legacy path walks the slot key by key with MIGRATE, which is where ASK redirects come from. It works, but it is slow on large slots, it generates a redirect storm while it runs, and an interrupted migration leaves the cluster in a state someone has to unpick by hand.
Both engines have now added atomic slot migration alongside it, and it is the most consequential cluster change in years. Instead of moving keys individually, the source forks a child process to snapshot the whole slot, streams subsequent writes behind the snapshot, and the destination takes ownership only once it is fully caught up — asynchronous, cancellable and all-or-nothing. Both implementations also hide importing slots from KEYS, SCAN and DBSIZE, so a keyspace walk cannot see half-migrated data (Redis notes that some FT.* and TS.* queries can still return partial or duplicated results mid-migration).
Because the source keeps ownership and every key until one atomic handoff, clients never see ASK or -TRYAGAIN under atomic migration — only a MOVED once ownership changes.
| Redis | Valkey | |
|---|---|---|
| Available since | 8.4 (November 2025) | 9.0 (October 2025) |
| Start | CLUSTER MIGRATION IMPORT | CLUSTER MIGRATESLOTS |
| Poll | CLUSTER MIGRATION STATUS | CLUSTER GETSLOTMIGRATIONS |
| Cancel | CLUSTER MIGRATION CANCEL | CLUSTER CANCELSLOTMIGRATIONS |
The mechanisms converged, but the control direction did not: on Redis you run CLUSTER MIGRATION IMPORT on the importing node, while on Valkey you run CLUSTER MIGRATESLOTS … NODE <target> on the exporting node. Runbooks and tooling are not portable between the two even though the operation is the same.
Note what this does not mean. Atomic migration is opt-in through those new commands only — the legacy path is still present, and as of Redis 8.4 and Valkey 9.0 it is still what redis-cli --cluster reshard and valkey-cli --cluster reshard drive. The command shown above uses it. Redis reports up to a 30× speedup and roughly 98% fewer client redirects for the atomic route on its own benchmark, so it is worth adopting deliberately rather than assuming you already have it. For the wider comparison, see Valkey vs Redis.
What Redis Cluster Takes Away
Cluster mode is not a transparent upgrade. Every item below breaks working single-node code.
| Constraint | What it means |
|---|---|
| Database 0 only | On Redis, SELECT to any database other than 0 is rejected, so code using numbered databases for namespacing needs key prefixes instead. Valkey 9.0 lifted this — cluster-databases (default 1) enables multiple databases in cluster mode |
| No cross-slot multi-key commands | MGET, SUNION, SINTERSTORE and friends fail with CROSSSLOT unless every key shares a slot |
| Transactions and Lua are slot-scoped | A MULTI/EXEC block or Lua script may only touch keys in one slot |
| Pub/Sub floods the cluster bus | Classic Pub/Sub broadcasts every message to every node, so it does not scale with cluster size. Redis 7.0's sharded Pub/Sub (SSUBSCRIBE/SPUBLISH) confines messages to one shard and does scale |
| One unassigned slot can stop everything | cluster-require-full-coverage defaults to yes: if any slot has no owner, the whole cluster returns CLUSTERDOWN. Setting no keeps the covered slots serving, and cluster-allow-reads-when-down separately keeps reads alive |
| Remapping needs explicit config | Nodes advertise their own addresses, so NAT and Docker bridge networking break discovery by default. Use host networking, or set cluster-announce-ip, cluster-announce-port and cluster-announce-bus-port |
| Still not strongly consistent | Replication stays asynchronous — an acknowledged write can be lost if its primary dies before replicating. WAIT narrows the window; it does not close it |
Redis Cluster vs Redis Sentinel
Both provide automatic failover; only Cluster shards. Sentinel keeps one full dataset on one primary and monitors it with a separate quorum of Sentinel processes, so it fits when the data comfortably fits in one node's memory but downtime does not fit the SLA. Cluster is what you reach for when the dataset or the write volume exceeds a single node — and it needs no extra processes, since the nodes monitor each other. See Redis Sentinel vs Redis Cluster for the full side-by-side. Note that a cluster has to be monitored per node: a cluster-wide average hides the one hot shard causing the incident.
Connecting to Redis Cluster From Java
A cluster-aware client must discover the topology, cache the slot map, follow redirects and re-discover after failover. Redisson handles all of it behind the same API used for a standalone server:
Config config = new Config();
config.useClusterServers()
// Seed nodes only — Redisson discovers the rest of the topology
.addNodeAddress("redis://10.0.0.1:6379", "redis://10.0.0.2:6379");
RedissonClient redisson = Redisson.create(config);
// Unchanged from standalone — routing is the client's problem, not yours
RMap<String, Order> orders = redisson.getMap("orders");
That is the whole configuration — the seed addresses are enough. Three defaults are worth knowing precisely because you inherit them without writing them down:
| Setting | Default | Why it matters |
|---|---|---|
readMode | SLAVE | Reads go to replicas by default, so you are already exposed to replication lag — a read-your-own-writes bug that surfaces only under load. Set ReadMode.MASTER where you need read-after-write consistency |
subscriptionMode | MASTER | Pub/Sub subscriptions attach to primaries. Moving them to replicas takes load off primaries at the cost of an extra hop |
scanInterval | 5000 ms | How often the topology is re-scanned, which bounds how quickly the client notices a failover. Lowering it shortens recovery at the cost of more chatter |
The one worth setting explicitly is checkSlotsCoverage (default true), the client-side mirror of cluster-require-full-coverage: it fails startup loudly on a partially covered cluster rather than serving confusing errors later. Leave it on.
Redisson also addresses the structural limitation this page keeps returning to. A single Redis collection lives in a single hash slot, and therefore on a single node — a 40 GB map does not shard just because the cluster has ten nodes, and it will hit that one node's memory ceiling while the others sit idle. Redisson PRO's data partitioning splits one logical structure across all cluster shards, with RClusteredMap, RClusteredSet, RClusteredBloomFilter and clustered topics. That is the case where cluster mode alone genuinely does not solve the problem it appears to.
For setup walkthroughs, see connecting to a Redis cluster in Java, running on Kubernetes, and upgrading a cluster with zero downtime.
Redis Cluster: Frequently Asked Questions
Why Does Redis Cluster Use 16,384 Hash Slots?
Redis creator Salvatore Sanfilippo has explained the choice as a message-size trade-off: each node advertises its slot ownership as a bitmap inside every cluster bus heartbeat, and at 16,384 slots that bitmap is 2 KB where at 65,536 it would be 8 KB — heavy traffic for a protocol where all nodes gossip continuously. 16,384 also sits far above any realistic cluster size — it is the hard ceiling on the number of primaries, and the suggested maximum is around 1,000 nodes.
How Many Nodes Does a Redis Cluster Need?
At least three primaries, because failover requires a majority vote among primaries and a majority is not meaningful below three. In production the standard is six nodes — three primaries each with one replica — since a primary with no replica cannot fail over — and by default an uncovered slot takes the whole cluster to CLUSTERDOWN, not just that shard.
What Is the Difference Between Redis Cluster and Redis Sentinel?
Cluster shards data across primaries and scales writes and memory; Sentinel keeps one complete dataset on one primary and only adds automatic failover. Cluster nodes monitor each other, while Sentinel needs its own separate quorum of processes. Use Sentinel when the dataset fits one node but downtime is unacceptable, and Cluster when the dataset or write volume does not fit one node.
Can Redis Cluster Run Multi-Key Commands?
Only when every key in the command maps to the same hash slot, otherwise the server returns a CROSSSLOT error. The way to guarantee that is a hash tag: brace a common substring, as in {user:42}:profile and {user:42}:cart, and only that substring is hashed. Use the narrowest tag your operations need — a broad tag pins large amounts of data to one node.
Does Redis Cluster Support Multiple Databases?
No. Cluster mode supports database 0 only, and rejects SELECT to any other database. Applications that used numbered databases to separate environments or tenants on a single instance need to switch to key prefixes, or to separate clusters, before migrating.
Does Redis Cluster Guarantee No Data Loss?
No. Replication is asynchronous, so a primary can acknowledge a write to the client and fail before that write reaches any replica — the promoted replica will never have seen it. Clients stranded in a minority partition can also write to a primary that has already been failed over elsewhere, though primaries stop accepting writes after cluster-node-timeout without majority contact, which bounds that window. The WAIT command narrows the exposure by blocking until a number of replicas acknowledge, but it does not make the system strongly consistent.