JusDB
Free DB Audit
NoSQL Databases

Valkey Cluster vs Sentinel: Choosing an HA Topology

Decide between Valkey Sentinel and Valkey Cluster on Valkey 9: data size limits, hash tags, numbered databases, client support, failover timing, and a migration runbook.

JusDB Team
Published October 27, 2026
Updated November 10, 2026
20 min read

Most self-managed Valkey deployments start as one primary, a replica or two, and three Sentinel processes. The cluster question comes up when the dataset outgrows one host, the main thread runs out of CPU, or a trial move to Valkey Cluster fails with CROSSSLOT Keys in request don't hash to the same slot. Valkey 9 changed part of the trade-off. Valkey 9.0 added numbered databases in cluster mode and atomic slot migration, and Valkey 9.1 added per-database ACLs and CLUSTERSCAN. Other parts did not change. Replication is still asynchronous in both topologies, multi-key commands in a cluster still need every key in one hash slot, and the two topologies need different client support. This guide compares the two on Valkey 9.1, explains failover in each (including where the documentation is out of date), and ends with a migration runbook.

TL;DR
  • Stay on Sentinel while the dataset, the fork headroom, and the write load fit on one primary. Move to Cluster when one primary is the limit: more replicas add read capacity, never write capacity.
  • Valkey Cluster splits keys into 16,384 hash slots. Multi-key commands, transactions, and Lua scripts work only when all their keys hash to one slot, so plan hash tags before you migrate.
  • Valkey 9.0 allows numbered databases in cluster mode, but cluster-databases defaults to 1, is set only at startup, and FLUSHDB, SCAN, and DBSIZE act on one node.
  • Both topologies replicate asynchronously and can lose acknowledged writes in a failover. Detection starts after down-after-milliseconds (30 seconds in the shipped sentinel.conf) or cluster-node-timeout (15 seconds by default).
  • valkey-cli --cluster import in 9.1.3 copies database 0 only, so a Sentinel deployment that uses several databases needs its own copy plan.

Scope and review date: November 2026. This post covers self-managed Valkey 9.1 (9.1.3, released 26 October 2026) and Valkey 9.0 (9.0.7), with notes where 8.x behaves differently. Defaults, command syntax, and version numbers were checked on 10 November 2026 against the valkey.io documentation, the 9.1.3 source and configuration files, and the GitHub release notes. The commands were not run in a lab, and the terminal output shown is illustrative, so rehearse every step on staging.


What is the difference between Valkey Sentinel and Valkey Cluster?

Sentinel is a separate process (valkey-sentinel, port 26379 by default) that watches a standalone primary and its replicas and promotes a replica when enough Sentinels agree the primary is down. Every data node holds the whole dataset, and all writes go to one primary.

Valkey Cluster is built into the server. The keyspace is split into 16,384 hash slots, each primary owns a set of slots, and the nodes talk to each other over a cluster bus on the client port plus 10000. Replicas of a failed primary are promoted by a vote of the other primaries. There is no Sentinel and no proxy. The cluster specification states a design goal of linear scaling up to 2,000 nodes.

ini
# sentinel.conf, on three hosts in separate failure domains
port 26379
sentinel monitor mymaster 10.0.1.12 6379 2
sentinel down-after-milliseconds mymaster 30000
sentinel failover-timeout mymaster 180000
sentinel parallel-syncs mymaster 1

# valkey.conf, on every Valkey Cluster node
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 15000

Interpretation: the last argument of sentinel monitor is the quorum: two of the three Sentinels must agree the primary is unreachable. The quorum only detects the failure. Starting the failover also needs a majority of all Sentinel processes. The server writes nodes.conf itself. The timing values match the defaults in the shipped 9.1.3 sentinel.conf and valkey.conf.

Standalone with Sentinel and Valkey Cluster side by side

Switch topologies to see what changes for data placement, failover, and your application

Standalone + Sentinel

AreaStandalone + Sentinel
Data placementWhole dataset on one primary; every replica holds a full copy
Write capacityOne primary
Failure detectionSDOWN after down-after-milliseconds, ODOWN when the quorum agrees
Who authorizes failoverA majority of Sentinel processes
Multi-key commands, MULTI, LuaAny keys
Numbered databasesdatabases 16 by default
Client requirementSentinel discovery protocol
Smallest sensible layout3 Sentinels, 1 primary, at least 1 replica

Valkey Cluster

AreaValkey Cluster
Data placement16,384 hash slots split across primaries; each replica copies one primary
Write capacityOne primary per shard
Failure detectionPFAIL after cluster-node-timeout, FAIL when a majority of primaries agree
Who authorizes failoverA majority of slot-owning primaries
Multi-key commands, MULTI, LuaOnly keys in one hash slot; otherwise CROSSSLOT
Numbered databasescluster-databases 1 by default; more since 9.0, set at startup
Client requirementCluster-aware client that follows MOVED and ASK
Smallest sensible layout3 primaries; the docs recommend 3 primaries and 3 replicas

Same replication underneath: both topologies copy writes to replicas asynchronously, so neither one makes failover lossless. The differences are where data lives, who votes, and what your client must understand.

When does one primary stop being enough?

The Valkey documentation gives no RAM or throughput number at which to shard. Find the crossover from four measurements on the current primary.

  • Memory with fork headroom. RDB snapshots and AOF rewrites fork a child process. Pages that change while the child runs are copied, so the host needs room for the dataset plus that copy. The persistence documentation warns that fork() on a big dataset can stop the server serving clients for milliseconds, or up to a second on a slow CPU.
  • Full sync time. A replica that resynchronizes receives the whole dataset, so a larger dataset means a longer period with one fewer replica.
  • Main-thread CPU. Commands execute on the main thread, and I/O threads take over network reads and writes. Valkey's 9.1 announcement reports 2.1 million requests per second on one server with 512-byte payloads, 9 I/O threads, and a pipeline depth of 10. That is the vendor's benchmark, not a capacity figure for your workload.
  • Write load. Sentinel can add replicas for reads, but every write still lands on one primary.
bash
# Run against the current primary at peak traffic
valkey-cli -h 10.0.1.12 INFO memory | grep -E '^(used_memory|used_memory_rss|maxmemory):'
valkey-cli -h 10.0.1.12 INFO persistence | grep -E '^(rdb_last_cow_size|aof_last_cow_size):'
valkey-cli -h 10.0.1.12 INFO stats | grep -E '^(instantaneous_ops_per_sec|latest_fork_usec):'
valkey-cli -h 10.0.1.12 INFO cpu | grep main_thread

Interpretation: add used_memory and the last copy-on-write size and compare the total with host RAM. latest_fork_usec is how long the last fork blocked the server, in microseconds. The used_cpu_user_main_thread and used_cpu_sys_main_thread counters are cumulative seconds: sample them twice, 60 seconds apart. If the difference approaches 60, the main thread is close to one full core and the primary is CPU bound.

Write the threshold down

Record the memory, fork, and CPU limits you accept and forecast growth against them. Start sharding early: the application changes take longer than a bigger host.

Will your multi-key commands work in Valkey Cluster?

Only if all the keys in one command hash to the same slot. The slot is CRC16(key) mod 16384. When a key contains a hash tag, only the text between the first { and the next } is hashed, so {user:1000}:cart and {user:1000}:profile always share a slot. The rule covers multi-key commands such as MGET and SUNION, MULTI/EXEC transactions, and Lua scripts that touch several keys.

The cluster tutorial sorts applications into three cases: no multi-key operations, multi-key operations that already share a hash tag, and multi-key operations without one. It states that the third case is not handled by Valkey Cluster, and the application has to change.

bash
valkey-cli -c -h 10.0.3.21 CLUSTER KEYSLOT user:1000:cart
valkey-cli -c -h 10.0.3.21 CLUSTER KEYSLOT user:1000:profile
valkey-cli -c -h 10.0.3.21 CLUSTER KEYSLOT '{user:1000}:cart'
valkey-cli -c -h 10.0.3.21 CLUSTER KEYSLOT '{user:1000}:profile'

Interpretation: the first two keys almost always land in different slots. The two tagged keys return the same slot number, so a transaction or script that uses both works on any cluster.

bash
10.0.3.21:6379> MGET user:1000:cart user:1000:profile
(error) CROSSSLOT Keys in request don't hash to the same slot

Interpretation: this is the error your application sees for case three. The same MGET works on a Sentinel primary, so the problem often first appears in cluster testing. During a reshard, a multi-key command on a slot that is being moved can also return -TRYAGAIN when its keys are split between the two nodes.

A hash tag is also a placement decision

Every key with the same tag lives on one primary. Tag by an entity with many values, such as a user or tenant ID. A constant tag such as {app} puts the whole keyspace in one slot and removes the point of the cluster.

Can you use SELECT and numbered databases in Valkey Cluster?

Yes, from Valkey 9.0. Before 9.0, a cluster had only database 0, which kept many multi-database Sentinel deployments off Cluster. The 9.0 release added cluster-databases (PR #1671). Three details matter:

  • cluster-databases defaults to 1, and the standalone databases setting is ignored in cluster mode.
  • The setting is immutable in the 9.1.3 source, so you set it in valkey.conf before a node starts, on every node.
  • The slot still depends only on the key name. FLUSHDB, SCAN, and DBSIZE act on the connected node's part of the database, and databases share CPU and memory with no isolation (Valkey blog: Numbered Databases in Valkey 9.0).
ini
# valkey.conf, on every cluster node, before the first start
cluster-enabled yes
cluster-databases 16
bash
# Valkey 9.1 and later: limit an application user to databases 0 and 1
valkey-cli -h 10.0.3.21 ACL SETUSER app-user on '>secretpass' '+@all' '~*' db=0,1

Interpretation: per-database ACLs arrived in 9.1. A user with this rule gets NOPERM when it selects database 2. ACL users are defined per server, so put the rule in an ACL file that your configuration tool ships to every node.

Two client details catch people. Some client libraries still allow only database 0 in cluster mode, and pooled or multiplexed clients can return a connection to the pool with a non-zero database still selected. If you run more than one database, run 9.0.7 or 9.1.3 or later before resharding: earlier 9.x releases could apply writes made during an atomic slot migration snapshot to the wrong database on the target (PR #4952).

Which clients work with Sentinel, and which with Cluster?

The Sentinel client specification asks the client to try each Sentinel in turn, ask it for the primary's address, confirm that address with ROLE, and ask again after every reconnect. A cluster client keeps a slot map, follows MOVED and ASK redirects, and refreshes the map with CLUSTER SHARDS or CLUSTER SLOTS.

  • Valkey GLIDE supports standalone and cluster mode but not Sentinel. As of November 2026, the Sentinel feature request is still open, with the maintainers reporting an investigation in October 2026.
  • Coordinated failover (9.0) can finish quickly. The Sentinel documentation warns that clients relying only on Sentinel pub/sub messages may reconnect to the demoted primary and get READONLY errors.
  • Command names. Valkey 8.0 added SENTINEL GET-PRIMARY-ADDR-BY-NAME as an alias of GET-MASTER-ADDR-BY-NAME (PR #789). The Sentinel command list still shows only the old name, and the cluster specification still calls CLUSTER SLOTS deprecated although 8.0 un-deprecated it (PR #536).

Where is the primary? One question, two topologies

Illustrative output: addresses, offsets, and counters are examples, not measurements

ops@bastion:~
$ valkey-cli -p 26379 SENTINEL GET-PRIMARY-ADDR-BY-NAME mymaster1) "10.0.1.12"2) "6379"$ valkey-cli -h 10.0.1.12 ROLE1) "master"2) (integer) 482133373) 1) 1) "10.0.2.12" 2) "6379" 3) "48213337"$ valkey-cli -h 10.0.3.21 CLUSTER INFOcluster_state:okcluster_slots_assigned:16384cluster_slots_ok:16384cluster_slots_pfail:0cluster_slots_fail:0cluster_nodes_pfail:0cluster_nodes_fail:0cluster_known_nodes:6cluster_size:3cluster_current_epoch:6

Verify, then trust: a Sentinel answer is confirmed with ROLE, as the Sentinel client specification requires. In a cluster, cluster_state:ok with 16384 slots assigned and zero pfail and fail counters is the healthy baseline (field meanings from the CLUSTER INFO reference).

How does failover work in each topology, and how long does it take?

Sentinel. Each Sentinel marks the primary subjectively down (SDOWN) after down-after-milliseconds without a valid reply. When the quorum agrees, the state becomes objectively down (ODOWN). A Sentinel then needs votes from a majority of Sentinels to lead the failover. It picks a replica by disconnection time, replica-priority, replication offset, and run ID, promotes it, and repoints the other replicas, parallel-syncs at a time.

Cluster. A node flags an unreachable peer as PFAIL after cluster-node-timeout. The flag becomes FAIL when a majority of primaries report it within twice the node timeout. The failed primary's replicas then wait an election delay and ask the primaries for votes. The replica that collects a majority takes over the slots.

The cluster specification still describes the older timing. It gives the delay as "500 milliseconds + random delay between 0 and 500 milliseconds + REPLICA_RANK * 1000 milliseconds", and says a primary will not vote for another replica of the same primary for twice the node timeout. Valkey 8.1 removed that vote limit (PR #1356). Valkey 9.0 made the delay relative to the node timeout (PR #2449). Valkey 9.1 lets the best-ranked replica start the election at once (PR #2227). This is the 9.1.3 logic:

bash
# Election delay in Valkey 9.1.3 (src/cluster_legacy.c)
# delay = min(cluster-node-timeout / 30, 500) ms   -> 500 ms at the 15000 default
# start = delay + random(0 .. delay) + rank * (2 * delay)
#         + failed-primary rank * delay (several primaries down at once)
#         + 500 ms if this replica's replication offset is 0
# Skipped entirely when this replica is rank 0, has data,
# and all replicas already see the primary as FAIL (9.1 and later)
valkey-cli -h 10.0.3.21 CONFIG GET cluster-node-timeout

Interpretation: detection dominates the outage. With defaults, a cluster primary is not even suspected for 15 seconds, while the election adds well under a second for the best replica. The specification says that after the node timeout, failovers usually take 1 or 2 seconds more. For Sentinel, the shipped sentinel.conf uses 30 seconds before SDOWN. Lower either only as far as normal network pauses allow, then drill-test it.

Unplanned failover: Sentinel and Valkey Cluster

Read each row left to right; the timer that starts the clock differs, the asynchronous replication does not

Unplanned failover in Sentinel and in Valkey Cluster Top row, Sentinel: the primary stops replying for down-after-milliseconds and each Sentinel marks it SDOWN; when the quorum agrees it becomes ODOWN; a majority of Sentinels elects a leader Sentinel; the leader promotes the best replica and clients ask Sentinel for the new address. Bottom row, Valkey Cluster: nodes flag the primary PFAIL after cluster-node-timeout; a majority of primaries confirm it as FAIL; the replicas wait an election delay based on their rank and ask for votes; the replica with a majority of primary votes takes over the slots and clients follow MOVED redirects. Standalone + Sentinel SDOWN down-after-ms ODOWN quorum agrees Leader vote Sentinel majority Promote clients re-ask Valkey Cluster PFAIL node-timeout FAIL primary majority Election rank-based delay Replica wins clients follow MOVED writes acknowledged by the old primary but not yet replicated can be lost in both rows

Where the time goes: the first box is the longest step in both rows. It is 30 seconds with the shipped sentinel.conf and 15 seconds at the default cluster-node-timeout.

Neither topology promises that acknowledged writes survive. To narrow the window, min-replicas-to-write and min-replicas-max-lag make a primary stop accepting writes when no replica has acknowledged recently, and WAIT lets a critical write block until replicas acknowledge it.

Planned failovers

For maintenance, use the planned path, which hands over without waiting for a timeout. On Sentinel, Valkey 9.0 added SENTINEL FAILOVER <name> COORDINATED, which drives the server's FAILOVER command between the primary and the chosen replica. One Sentinel trap: Valkey 9.0.0 made every failover fail when the Sentinel user had the documented pre-9.0 ACL, and 9.0.1 fixed it so that only COORDINATED needs +failover (PR #2780). In a cluster, run CLUSTER FAILOVER on a replica, or set shutdown-on-sigterm failover (9.0 and later) so a primary that receives SIGTERM first hands its slots to a fully synced replica, when one exists.

bash
# Sentinel, Valkey 9.0 and later
valkey-cli -p 26379 SENTINEL FAILOVER mymaster COORDINATED

# Cluster: run on the replica that should become primary
valkey-cli -h 10.0.3.24 CLUSTER FAILOVER

Interpretation: a manual cluster failover pauses writes on the primary until the replica has caught up, for at most cluster-manual-failover-timeout (5000 ms by default). Plan for that short write pause in each maintenance window.

What does each topology cost to run?

Sentinel needs at least three Sentinel processes on hosts that fail independently, plus the primary and at least one replica. The cluster tutorial says a working cluster needs at least three primaries and recommends six nodes: three primaries and three replicas. Every cluster node also needs its bus port (client port plus 10000) open to every other node.

Then count the failure modes you take on:

  • Whole-cluster stops. With cluster-require-full-coverage yes (the default), the cluster stops accepting queries when any slot has no working owner, for example when a shard loses its primary and all its replicas. Set it to no only if serving part of the keyspace is better than serving none.
  • Resharding. Valkey 9.0 added atomic slot migration, which moves whole slots instead of one key at a time, and 9.1 added --cluster-use-atomic-slot-migration to valkey-cli --cluster reshard and rebalance.
  • Per-node work. Configuration, ACLs, and many commands act on one node; 9.1 added CLUSTERSCAN for cluster-wide key scans.
  • Restarts without persistence. The replication documentation explains that Sentinel identifies instances by address. A primary that restarts empty at the same address can make its replicas copy the empty dataset. A cluster node that starts without its nodes.conf gets a new node ID and joins as a new, empty node instead.
bash
# Cluster health and slot balance, Valkey 9.1
valkey-cli --cluster check 10.0.3.21:6379
valkey-cli --cluster rebalance 10.0.3.21:6379 --cluster-use-atomic-slot-migration

# Sentinel health: can this deployment still reach quorum and majority?
valkey-cli -p 26379 SENTINEL CKQUORUM mymaster

Interpretation: --cluster check reports slot coverage and open slots. SENTINEL CKQUORUM confirms enough Sentinels are reachable to detect a failure and authorize a failover. Run both from monitoring.

How do you migrate from Sentinel to Valkey Cluster?

The cluster tutorial states that no automatic live migration to Valkey Cluster exists. Its documented paths stop the clients: either load each source node's AOF into a new cluster and run valkey-cli --cluster fix, or copy keys from a running instance with valkey-cli --cluster import. The 9.1.3 source shows that import moves database 0 only, and it deletes the keys from the source unless you pass --cluster-copy. The cluster specification has not caught up with multi-database clusters: it still says MIGRATE never needs a database other than 0.

Runbook: standalone with Sentinel to Valkey Cluster

Eight steps; steps 5 to 7 are the write-pause window

  1. Inventory multi-key access and databases

    List every database with keys, and find transactions, scripts, and multi-key commands in the code.

    valkey-cli -h 10.0.1.12 INFO keyspace
  2. Add hash tags and ship them on Sentinel

    Hash tags are ordinary key names, so the renamed keys work on the current primary too. Ship and backfill them before the cluster exists.

  3. Build the cluster on 9.1.3

    Set cluster-databases in every node's config before the first start if you need more than database 0.

    valkey-cli --cluster create 10.0.3.21:6379 \ 10.0.3.22:6379 10.0.3.23:6379 10.0.3.24:6379 \ 10.0.3.25:6379 10.0.3.26:6379 \ --cluster-replicas 1
  4. Switch clients to cluster mode on staging

    Run the full test suite against the new cluster and watch for CROSSSLOT errors and database 0 assumptions.

  5. Stop writes to the Sentinel primary

    Write pause starts

    Stop or pause the writers. Keys written after this point are not copied.

  6. Copy database 0 into the cluster

    Write pause

    Copy keeps the source intact for rollback. Copy other databases with your own per-database script.

    valkey-cli --cluster import 10.0.3.21:6379 \ --cluster-from 10.0.1.12:6379 \ --cluster-copy
  7. Verify and repoint the applications

    Write pause ends

    Check slot coverage and compare key counts per database, summed across primaries, with the source.

    valkey-cli --cluster check 10.0.3.21:6379
  8. Keep Sentinel for the rollback window

    Leave the old primary untouched and read-only until the cluster has run a full business cycle, then retire it.

Rollback point: until step 7, the Sentinel primary still holds every key because step 6 used --cluster-copy. After applications write to the cluster, rolling back means copying those writes back by hand.

bash
# After step 7: key count for one database across all cluster primaries
for n in 10.0.3.21 10.0.3.22 10.0.3.23; do
  valkey-cli -h "$n" -n 0 DBSIZE
done

Interpretation: DBSIZE in cluster mode counts only the connected node's keys, so sum the primaries and compare with INFO keyspace from step 1. Repeat with -n 1 and up for each extra database, using the nodes that are primaries.

Frequently asked questions

Is Valkey Sentinel or Valkey Cluster better for high availability?

Neither is more available by design. Both detect a failed primary, promote a replica, and replicate asynchronously, so both can lose recent writes. Sentinel suits a dataset that fits one primary. Valkey Cluster suits data or write load that needs several primaries, and it requires a cluster-aware client and hash tags for multi-key commands.

Can I use multiple databases with SELECT in Valkey Cluster?

Yes, from Valkey 9.0. Set cluster-databases in valkey.conf on every node before it starts, because the default is 1 and the setting cannot change at runtime. FLUSHDB, SCAN, and DBSIZE then act on the connected node only. If you reshard with several databases, run 9.0.7 or 9.1.3 or later.

How long does a Valkey failover take?

Mostly as long as failure detection. Sentinel waits down-after-milliseconds, 30 seconds in the shipped sentinel.conf, before a Sentinel marks the primary down. Valkey Cluster waits cluster-node-timeout, 15 seconds by default. Election and promotion add seconds or less on top. Measure your own timing with a failover drill on staging.

Do I need Sentinel with Valkey Cluster?

No. Valkey Cluster detects failures and promotes replicas itself, using votes from the primaries that own hash slots. Sentinel is for standalone primaries with replicas, and it repoints replicas with REPLICAOF, a command that Valkey does not allow in cluster mode. Pick one topology per deployment.

Key takeaways

  • Move from Sentinel to Cluster when memory with fork headroom, main-thread CPU, or write load outgrows one primary. Measure these with INFO rather than relying on a rule of thumb.
  • Audit multi-key commands, transactions, and scripts first, and ship hash tags on the Sentinel deployment before the cluster exists.
  • Valkey 9.0 brings numbered databases to clusters, but set cluster-databases at startup, expect per-node DBSIZE and FLUSHDB, and run 9.0.7 or 9.1.3 or later.
  • Failover time is mostly detection time. The cluster specification's election timing predates Valkey 8.1, 9.0, and 9.1, so read the release notes when you tune it.
  • valkey-cli --cluster import copies database 0 only. Use --cluster-copy so the Sentinel primary stays your rollback.

Plan your Valkey HA topology with JusDB

JusDB's Valkey high availability team can review your current Sentinel or cluster layout, measure the memory, fork, and CPU limits of your primary, and plan the move to Valkey Cluster, including hash tag changes, client checks, and a rehearsed failover drill on staging.

Bring your Valkey versions, topology, INFO output from peak traffic, and client libraries. Your team approves every production change.

Share this article

Database engineering notes

Articles like this one, in your inbox. No spam, unsubscribe anytime.

JusDB Team

Official JusDB content team

Keep reading

Moving a Multi-Database Valkey Instance into a 9.x Cluster

Move a Valkey instance that uses SELECT 1 to 15 into a 9.x cluster: keep or remap databases, copy each one, verify counts per database, and keep a way back.

Redis18 minNov 10, 2026
Read

Valkey Keyspace Notifications in Production: Expired Events, hexpired and Cluster Mode

Run Valkey keyspace notifications in production: why expired and hexpired events lag the TTL, how to subscribe on every cluster node, and when a stream is safer.

Redis20 minNov 10, 2026
Read

Valkey GLIDE in Production: AZ-Affinity Reads and Migrating from Legacy Clients

Configure Valkey GLIDE AZ-affinity reads on servers and clients, learn what GLIDE 2.5.3 does not support, and migrate from redis-py, Jedis, ioredis, or go-redis one service at a time.

Redis20 minNov 10, 2026
Read