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.
- 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-databasesdefaults to 1, is set only at startup, andFLUSHDB,SCAN, andDBSIZEact 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 shippedsentinel.conf) orcluster-node-timeout(15 seconds by default). valkey-cli --cluster importin 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.
# 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 15000Interpretation: 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
| Area | Standalone + Sentinel |
|---|---|
| Data placement | Whole dataset on one primary; every replica holds a full copy |
| Write capacity | One primary |
| Failure detection | SDOWN after down-after-milliseconds, ODOWN when the quorum agrees |
| Who authorizes failover | A majority of Sentinel processes |
| Multi-key commands, MULTI, Lua | Any keys |
| Numbered databases | databases 16 by default |
| Client requirement | Sentinel discovery protocol |
| Smallest sensible layout | 3 Sentinels, 1 primary, at least 1 replica |
Valkey Cluster
| Area | Valkey Cluster |
|---|---|
| Data placement | 16,384 hash slots split across primaries; each replica copies one primary |
| Write capacity | One primary per shard |
| Failure detection | PFAIL after cluster-node-timeout, FAIL when a majority of primaries agree |
| Who authorizes failover | A majority of slot-owning primaries |
| Multi-key commands, MULTI, Lua | Only keys in one hash slot; otherwise CROSSSLOT |
| Numbered databases | cluster-databases 1 by default; more since 9.0, set at startup |
| Client requirement | Cluster-aware client that follows MOVED and ASK |
| Smallest sensible layout | 3 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.
# 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_threadInterpretation: 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.
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.
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.
10.0.3.21:6379> MGET user:1000:cart user:1000:profile
(error) CROSSSLOT Keys in request don't hash to the same slotInterpretation: 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.
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-databasesdefaults to 1, and the standalonedatabasessetting is ignored in cluster mode.- The setting is immutable in the 9.1.3 source, so you set it in
valkey.confbefore a node starts, on every node. - The slot still depends only on the key name.
FLUSHDB,SCAN, andDBSIZEact 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).
# valkey.conf, on every cluster node, before the first start
cluster-enabled yes
cluster-databases 16# 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,1Interpretation: 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
READONLYerrors. - Command names. Valkey 8.0 added
SENTINEL GET-PRIMARY-ADDR-BY-NAMEas an alias ofGET-MASTER-ADDR-BY-NAME(PR #789). The Sentinel command list still shows only the old name, and the cluster specification still callsCLUSTER SLOTSdeprecated 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
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:
# 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-timeoutInterpretation: 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
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.
# 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 FAILOVERInterpretation: 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 tonoonly 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-migrationtovalkey-cli --cluster reshardandrebalance. - Per-node work. Configuration, ACLs, and many commands act on one node; 9.1 added
CLUSTERSCANfor 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.confgets a new node ID and joins as a new, empty node instead.
# 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 mymasterInterpretation: --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
-
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 -
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.
-
Build the cluster on 9.1.3
Set
cluster-databasesin 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 -
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.
-
Stop writes to the Sentinel primary
Write pause startsStop or pause the writers. Keys written after this point are not copied.
-
Copy database 0 into the cluster
Write pauseCopy 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 -
Verify and repoint the applications
Write pause endsCheck slot coverage and compare key counts per database, summed across primaries, with the source.
valkey-cli --cluster check 10.0.3.21:6379 -
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.
# 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
doneInterpretation: 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
INFOrather 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-databasesat startup, expect per-nodeDBSIZEandFLUSHDB, 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 importcopies database 0 only. Use--cluster-copyso 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.