Sentinel vs Cluster: Which Failover Model to Choose
Two Redis deployments can both survive a node loss, yet arrive at completely different architectures. Redis Sentinel keeps a single primary with replicas and promotes one on failure; Redis Cluster shards data across many primaries, each with its own replicas, and fails each shard over independently. Teams routinely reach for Cluster because it sounds more capable, then inherit cross-slot restrictions and a heavier client for a dataset that fit comfortably in one node's memory. The right choice is not about which is "more highly available" — both give automatic failover — but about whether your dataset and write throughput actually need horizontal partitioning, and whether your client and your operations team can absorb what partitioning costs. This page turns that call into a repeatable procedure: measure the footprint, decide if sharding is genuinely required, confirm client support, weigh the ops burden, pick, and plan a migration that does not require a maintenance window.
Prerequisites
- A running Redis 7.x instance you can inspect with
redis-cli,INFO, and--bigkeys. redis-py5.x on Python 3.10+ (pip install "redis>=5,<6"); the async examples importredis.asyncio.- A rough model of peak write throughput (ops/sec) and projected dataset growth over the next 12 months.
- Read access to your application's Redis call sites, so you can audit for multi-key operations and Lua scripts.
- Familiarity with how a single-primary deployment fails over — see Configuring Redis Sentinel Quorum for Automatic Failover for the Sentinel mechanics this page assumes.
Step-by-Step Decision Procedure
1. Size the dataset and its growth curve
Start with the memory footprint, because a dataset that fits in one node with headroom removes the primary reason to shard. Pull the resident size and the largest keys so you know both the total and its distribution.
redis-cli INFO memory | grep -E "used_memory_human|maxmemory_human"
redis-cli --bigkeys # surfaces the largest keys that dominate the footprint
2. Decide whether you actually need sharding
Sharding is justified when the working set will not fit one node's memory, or when write throughput exceeds what a single primary's event loop can absorb — reads scale on replicas without sharding at all. If both fit one primary today and for the planned horizon, Sentinel is sufficient; if not, Cluster earns its complexity.
def needs_sharding(dataset_gb: float, node_ram_gb: float, write_ops_per_sec: int,
single_node_write_ceiling: int = 80_000) -> bool:
# Shard only when memory or write throughput exceeds one primary.
# Reads do not force sharding — add replicas instead.
memory_bound = dataset_gb > node_ram_gb * 0.7 # keep 30% headroom
write_bound = write_ops_per_sec > single_node_write_ceiling
return memory_bound or write_bound
3. Check client library and command support
Cluster forbids multi-key operations whose keys land in different slots, so an application full of MGET, MSET, multi-key transactions, or Lua scripts over unrelated keys needs a hash-tag audit before it can run on Cluster. Grep the call sites and confirm your client speaks the Redis cluster protocol.
# find multi-key and scripted call sites that Cluster constrains
grep -rEn "mget|mset|pipeline|register_script|eval\(" app/ | wc -l
python -c "from redis.asyncio.cluster import RedisCluster; print('cluster client OK')"
4. Evaluate the operational burden
Sentinel adds three observer processes around a topology you already understand; Cluster adds slot ownership, resharding, and the MOVED/ASK redirection protocol your clients must handle. Weigh who operates it: Cluster's power comes with runbooks for MOVED redirection and slot rebalancing that Sentinel simply does not have.
# Cluster introduces slot state you must monitor and, eventually, rebalance
redis-cli -c CLUSTER INFO | grep -E "cluster_state|cluster_slots_assigned"
redis-cli -c CLUSTER SLOTS # empty on a Sentinel deployment — nothing to manage
5. Make the pick against the matrix
Combine the signals: dataset fits one node and command set uses multi-key operations freely → Sentinel; dataset or write load exceeds one node and the client can handle slots → Cluster. When only reads are the pressure, neither forces sharding — scale reads with replicas per replication and read scaling.
def choose_model(dataset_gb, node_ram_gb, write_ops, uses_cross_key_ops: bool) -> str:
if needs_sharding(dataset_gb, node_ram_gb, write_ops):
# Cross-key ops still work under Cluster only via hash tags.
return "cluster (audit hash tags first)" if uses_cross_key_ops else "cluster"
return "sentinel"
6. Plan the migration path
If you land on Cluster after starting on Sentinel, migrate by dual-writing or by seeding a Redis Cluster from a replica's RDB, then cutting clients over — never by editing config in place. Keep the Sentinel deployment serving until the Redis Cluster reports every slot assigned and clients resolve cleanly.
# verify the target Cluster owns all 16384 slots before cutting traffic over
redis-cli -c CLUSTER INFO | grep cluster_slots_assigned # must read 16384
Failure Modes
Cluster chosen for a single-node dataset. A team adopts Cluster for a footprint that fit one primary, then hits CROSSSLOT errors on every MGET and multi-key transaction. Diagnose by counting how many nodes actually hold data and how full each is:
redis-cli -c CLUSTER SHARDS | grep -c '"role":"master"' # how many primaries
redis-cli -c INFO keyspace # keys per node
If one shard holds nearly everything and the others idle, the sharding buys nothing while imposing cross-slot limits — collapse back to Sentinel or co-locate keys with hash tags.
Sentinel outgrown silently. A Sentinel deployment nears its single-node memory ceiling and starts evicting the working set instead of scaling out. Diagnose by watching eviction against the memory cap:
redis-cli INFO stats | grep evicted_keys
redis-cli INFO memory | grep -E "used_memory_human|maxmemory_human"
Rising evicted_keys at a full maxmemory means the dataset has outgrown one node — this is the signal to migrate to Cluster (Step 6), not to buy a bigger box indefinitely.
Client not cluster-aware. After moving to Cluster, an application built for a single endpoint loops on MOVED replies because its client cannot follow redirection. Diagnose with a redirection-heavy command against a plain client:
redis-cli -h cluster-node-1 -p 6379 GET some:key # returns MOVED without -c
Fix by using RedisCluster (not Redis) so the client caches the slot map and routes directly, and back it with Sentinel-aware or cluster-aware pooling from connection pooling.
Verification
Confirm the model you picked matches the footprint you measured — a Redis Cluster should spread keys across shards, not pile them on one:
redis-cli -c CLUSTER SLOTS # expect ranges owned by multiple primaries
redis-cli -c INFO keyspace # keys should not concentrate on a single node
For a Sentinel choice, confirm a single writable primary with healthy replicas and no orphaned slot state:
redis-cli -p 26379 SENTINEL MASTER mymaster | grep -E "num-slaves|flags"
redis-cli CLUSTER INFO | grep cluster_enabled # expect 0 on a Sentinel node
Prove the application resolves correctly against whichever model you chose:
async def verify_topology(expect_cluster: bool) -> None:
import redis.asyncio as redis
from redis.asyncio.cluster import RedisCluster
if expect_cluster:
rc = RedisCluster(host="cluster-node-1", port=6379)
assert len((await rc.cluster_nodes())) > 1 # more than one primary
else:
r = redis.Redis(host="primary", port=6379)
assert (await r.execute_command("ROLE"))[0] == "master"
FAQ
Can I run Sentinel and Cluster together?
Not on the same nodes — they are mutually exclusive failover models. Redis Cluster manages its own failover internally through the gossip protocol and per-shard elections, so it neither needs nor works with Sentinel. What you can do is run Sentinel-managed deployments for some services and a Redis Cluster for others within the same estate; each stays independent, and each client connects with the matching driver.
Is a single-shard Cluster equivalent to Sentinel?
Functionally you can run Cluster with one shard, but it is rarely worth it. You inherit the Redis cluster protocol, the client complexity, and the slot map for a topology that Sentinel handles more simply, while gaining none of the horizontal-scale benefit that justifies Cluster. Unless a single-shard Cluster is an explicit first step toward multi-shard growth, Sentinel is the lighter choice for a single primary.
Which failover model does redis-py support best?
Both are first-class in redis-py 5.x, but through different clients. Sentinel deployments use redis.asyncio.sentinel.Sentinel and its master_for resolver; Cluster deployments use redis.asyncio.cluster.RedisCluster, which caches the slot map and follows MOVED/ASK redirection automatically. The clients are not interchangeable, so the model you choose dictates which one your connection layer instantiates.
What is the migration path from Sentinel to Cluster?
Stand up a new Cluster alongside the running Sentinel deployment rather than converting in place. Seed it — dual-write from the application, or restore a replica's RDB into the new primaries — then wait until CLUSTER INFO reports all 16384 slots assigned and the state is ok. Cut clients over to the RedisCluster driver, audit any cross-key operations for hash tags first, and keep Sentinel serving reads until the cutover is verified. Slot rebalancing after that point follows the MOVED redirection model.
Up: Redis Sentinel vs Cluster Failover