You Probably Don't Need Redis Cluster
Redis Cluster sounds like the grown-up choice. In my experience it's usually the wrong one. Sentinel with a single replica gets you 95% of the way there for a fraction of the operational pain.
Redis Cluster has great marketing. The name alone sounds like the responsible choice - the thing you reach for when you're serious about uptime. I've made that mistake. Twice. These days I run Sentinel with a single replica for almost every client workload I touch, and I sleep better for it.
What Redis Cluster Actually Does (and Costs You)
Redis Cluster shards your keyspace across multiple primary nodes using consistent hashing. Keys get a hash slot (0-16383) and each node owns a range of slots. That means you can spread data and write throughput across machines in a way a single primary can never do.
The catch is that you're paying for that in several ways:
- Minimum three primaries. The cluster bus requires it. You're not running three nodes, you're running six if you want any replication at all.
- Multi-key operations get complicated.
MGET, pipelines, Lua scripts, transactions - they all have to touch the same hash slot or they fail. Cross-slot operations are just not allowed. - Your client library has to be cluster-aware. PhpRedis, Predis, ioredis - they all handle it, but you're now relying on the client to follow
MOVEDandASKredirections. That adds latency and debugging surface area. - Resharding is not painless. When you add or remove a node, slots migrate. It's automated, but it's not invisible.
For most of the workloads I deal with - session storage, cache keys, rate limiting, pub/sub, job queues - none of that horizontal scale is needed. And the operational overhead is real.
What Sentinel Actually Gives You
Sentinel solves the problem most applications actually have: "what happens when my Redis primary goes down at 2am?"
You run a primary, one replica, and three Sentinel processes (they can live on the same boxes as your Redis nodes plus your app server). Sentinel monitors the primary, reaches a quorum when it detects a failure, and promotes the replica. Your application reconnects and keeps going. Failover in a healthy setup takes 10-30 seconds.
That's it. That's the whole thing. No hash slots. No cross-slot restrictions. No six-node minimum. No client library redirect handling. MGET just works. Lua scripts just work.
For a healthcare client I support in Seattle, they were running a Laravel app with Redis for sessions and cache. Someone upstream suggested Cluster because "it scales." Their peak load is maybe 500 concurrent users. They had one Redis node, no replication, no Sentinel. The right answer was not Cluster - it was add a replica and wire up Sentinel. Done in an afternoon. They've had one primary failure since then. Sentinel caught it, promoted the replica, we were back in under 20 seconds, nobody called me.
Setting This Up in Laravel
Here's roughly how I configure this in a Laravel application. The redis driver in Laravel (via PhpRedis or Predis) supports Sentinel natively.
First, config/database.php:
'redis' => [
'client' => env('REDIS_CLIENT', 'phpredis'),
'options' => [
'replication' => 'sentinel',
'service' => env('REDIS_SENTINEL_SERVICE', 'mymaster'),
'parameters' => [
'password' => env('REDIS_PASSWORD', null),
'database' => 0,
],
'sentinel_timeout' => 0.100, // 100ms connect timeout to sentinels
'retry_limit' => 20,
'retry_interval' => 1000, // microseconds between retries
'update_sentinels' => true,
],
'default' => [
['host' => env('REDIS_SENTINEL_HOST_1', '10.0.0.10'), 'port' => 26379],
['host' => env('REDIS_SENTINEL_HOST_2', '10.0.0.11'), 'port' => 26379],
['host' => env('REDIS_SENTINEL_HOST_3', '10.0.0.12'), 'port' => 26379],
],
'cache' => [
['host' => env('REDIS_SENTINEL_HOST_1', '10.0.0.10'), 'port' => 26379],
['host' => env('REDIS_SENTINEL_HOST_2', '10.0.0.11'), 'port' => 26379],
['host' => env('REDIS_SENTINEL_HOST_3', '10.0.0.12'), 'port' => 26379],
],
],
The service key matches the name you configured in your sentinel.conf - typically mymaster unless you've changed it. The array of hosts are your Sentinel processes, not your Redis primaries. The client asks a Sentinel where the current primary is, then connects to it directly.
Your sentinel.conf on each Sentinel node looks like this:
port 26379
sentinel monitor mymaster 10.0.0.10 6379 2
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 60000
sentinel parallel-syncs mymaster 1
The 2 in sentinel monitor is the quorum - how many Sentinels have to agree the primary is down before triggering failover. With three Sentinels, 2 is correct. Never run with quorum of 1, that way lies split-brain.
On the replica side, your redis.conf is a one-liner addition:
replicaof 10.0.0.10 6379
After failover, Sentinel reconfigures both nodes automatically. You don't touch it.
The Gotchas That Will Bite You
Persistence settings matter more than you think. If your primary crashes hard and comes back before Sentinel promotes the replica, it comes back empty (if you're running no persistence) and the replica syncs to the empty primary. You just lost your data. Use appendonly yes or save directives, or accept that your data is ephemeral and design for it. Know which one you've chosen.
Sentinel quorum and the two-node trap. I've seen people run two Sentinels thinking "quorum of 1 is fine." It's not. With two nodes and quorum 1, either Sentinel can declare the primary dead and trigger failover independently. If you have a network partition, both sides think they're authoritative. Run three Sentinels. They're cheap processes.
The min-replicas-to-write setting. By default a Redis primary will accept writes even when it has no connected replicas. If you care about not losing data during the window between primary failure and failover completion, set:
min-replicas-to-write 1
min-replicas-max-lag 10
This tells the primary to stop accepting writes if it can't reach at least one replica within 10 seconds. Your app gets an error instead of silently writing data that will never make it to the replica. Whether that tradeoff is right depends on your app - for a cache it probably isn't, for session data it might be.
PhpRedis vs Predis Sentinel behavior. PhpRedis handles Sentinel reconnection better in my experience. If you're on Predis and seeing intermittent connection errors during failover windows, switching to PhpRedis is worth trying before you go debugging your Sentinel config.
Sentinel doesn't scale reads. If you need to distribute read load across the primary and replica, Sentinel alone doesn't do that for you. You'd need to wire your application to intentionally route reads to the replica. Some Redis clients support a preferreplica option. I've done this once, for a reporting workload hitting a large sorted set, and it was a small amount of custom code. If read distribution is your actual problem, that's worth solving specifically - not by reaching for Cluster.
When I'd Actually Reach for Cluster
There are real reasons to run Cluster. Here's what I'd want to see before making that call:
- Dataset larger than a single machine's RAM. If you genuinely can't fit your working set on one node, sharding is unavoidable. Cluster is the right answer here.
- Write throughput that saturates a single primary. This is rarer than people think. Redis is fast. A single primary can handle hundreds of thousands of operations per second. If you've measured and you're actually hitting that wall, Cluster is the tool.
- You've already simplified your key access patterns. Cross-slot restrictions hurt you if your code does arbitrary multi-key operations. If you're going to Cluster, audit your code first. Use hash tags to co-locate keys that have to be touched together.
I have one client - a print management company running very high job queue throughput - where Cluster made sense. High write rates, multiple producers, the queue depth genuinely warranted it. That's one out of maybe fifteen Redis deployments I actively manage.
When I Wouldn't
- You have fewer than a few thousand requests per second touching Redis.
- Your primary use case is caching or sessions.
- You're running on managed Redis (ElastiCache, Upstash, Redis Cloud) - they handle failover for you anyway and Cluster costs more for no additional reliability in that tier.
- Your team doesn't have someone who understands resharding before they need to do it under pressure.
Closing
Cluster is the right answer to a problem most applications don't have. If your Redis instance goes down and you have no replication, that's the actual fire - not horizontal scale. Sentinel and one replica fix the real problem, don't add cross-slot restrictions to your codebase, and don't require six nodes to be minimally viable. Start there. Migrate to Cluster when you have a measurement that says you need it, not a feeling.
Need help shipping something like this? Get in touch.