How to Upgrade a Valkey Cluster With Zero Downtime
If you run Valkey in cluster mode, staying current is one of the less stressful things on your roadmap. Valkey inherited the Redis 7.2.4 codebase at the fork and kept the cluster design intact, so the upgrade mechanics - graceful failover for a rolling upgrade, replicate-and-cut-over for a blue-green one - are the same ones any cluster of this lineage uses. This guide doesn't re-derive them from scratch; where the procedure is shared, it points you to the detailed walkthrough and keeps the focus on what's actually specific to Valkey: a compatibility contract that makes routine upgrades nearly boring, an atomic slot-migration engine that defuses the single riskiest part of an upgrade, and a licensing story that means moving up never changes your terms.
Where You Are, and Where You're Going
Valkey started at 7.2.4 - the last BSD-licensed Redis release - and ships on a deliberately slow, stability-first cadence of roughly one major version a year:
- 7.2.x - the fork point, still maintained with security patches.
- 8.0 - Valkey's first original major release.
- 9.0 - the second major. The headline for cluster operators is atomic slot migration, alongside per-field hash TTLs and numbered databases that finally work in cluster mode.
- 9.1 (May 2026) - the latest, adding a new I/O threading model, per-database access control, and a reorganization of the Lua scripting engine into a module.
The effort of an upgrade is roughly proportional to how many major boundaries it crosses. A 9.0 → 9.1 step is a minor bump and effectively routine; a 7.2 → 9.1 jump crosses two majors and earns the careful path. Deciding which one you're doing settles every other choice below.
Why Upgrades Are Usually Low-Drama (and Where They Aren't)
Valkey publishes an explicit backward-compatibility contract tied to semantic versioning: command behavior, the Lua scripting API, and the persistence formats are stable across patch and minor releases, and patch upgrades are meant to be drop-in. That contract is the reason the in-place path is the sensible default for the common case - a newer node can sit in the same cluster as older ones long enough to roll through them one at a time.
The guarantee stops at major boundaries. Crossing one (7.2 → 8, or 8 → 9) is where a rare behavioral change or a new operational requirement can surface, so a major jump is the case that justifies the more elaborate, fully reversible path. When in doubt, the deciding question is simple: small version gap and unchanged hardware → roll in place; big jump, or you're also changing topology or instances → go blue-green.
The Two Paths, in Brief
The full step-by-step for both - the exact CLUSTER FAILOVER ordering and the Redisson pub/sub cutover - is identical for any cluster of this lineage and is covered in detail in the zero-downtime Redis cluster upgrade guide. Here's the short version with the Valkey commands.
Rolling in-place. Work shard by shard, and never upgrade a node while it's the active primary for live slots:
- Upgrade a replica, let it resync from the still-older primary, and confirm
master_link_status:up:valkey-cli -c -h <replica-host> -p <port> INFO replication - Promote it with a graceful, cluster-aware failover, issued on the replica itself:
valkey-cli -c -h <replica-host> -p <port> CLUSTER FAILOVER - Upgrade the old primary, now a replica, and let it rejoin.
Repeat per shard; a healthy primary always serves every slot.
Blue-green. Stand up a new-version cluster, stream the live keyspace into it with a replication tool (RedisShake or redis-replicator, in PSYNC or SCAN mode - the tool emulates a replica, you don't point clusters at each other with REPLICAOF), then flip clients in one command using Redisson PRO's Multi Cluster mode. Redisson speaks Valkey natively, so the addresses use the valkey:// scheme (valkeys:// for TLS):
multiClusterServersConfig:
addresses:
- "valkey://valkey-old.example.com:6379" # cluster 1 - current version, primary at start
- "valkey://valkey-new.example.com:6379" # cluster 2 - new version, passive target
datastoreMode: ACTIVE
primaryDiscoveryMode: FIRST_PRIMARY_PUBSUB_NOTIFICATION
registrationKey: "YOUR_REDISSON_PRO_LICENSE_KEY"
FIRST_PRIMARY_PUBSUB_NOTIFICATION keeps the first address (cluster 1) as primary and has every Redisson instance watch the control channel redisson:multicluster:primary; the switch happens only when you publish the new primary's host:port to that channel from the current primary cluster. Until then, the app reads and writes against the old cluster as normal, with no code changes.
So once replication has caught up, publish the new cluster's host:port on that channel from the current primary, and every Redisson instance switches atomically:
valkey-cli -c -h valkey-old.example.com -p 6379 \
PUBLISH redisson:multicluster:primary "valkey-new.example.com:6379"
The reason to reach for blue-green is reversibility: the old cluster sits untouched until you decommission it, so rollback is just re-publishing its endpoint on the same channel.
Atomic Slot Migration: The Valkey 9 Change That De-Risks Upgrades
Here is where a Valkey upgrade genuinely diverges from its Redis ancestor, and it matters most exactly when an upgrade is riskiest - when you're rebalancing or adding shards at the same time.
On this lineage, slots historically migrated key by key, using a move-then-delete sequence. While a slot was half-moved, a client asking for a key in that slot couldn't be sure whether it still lived on the source node or had already landed on the target, which meant extra network hops and, in corner cases, degraded performance, stalled migrations, or lost data. It was the kind of hazard that made operators schedule maintenance windows for what should be a routine operation.
Valkey 9.0 replaced that with atomic slot migration: a slot moves as a single unit, so there is no ambiguous in-between state for a client to trip over. The practical effect on upgrades is concrete - if you're folding a reshard into the upgrade (say, moving to bigger nodes and rebalancing as you go, or growing from six shards to nine), and your target is Valkey 9 or later, the resharding step is dramatically safer than it used to be. It doesn't make a two-major jump trivial, but it removes one of the classic in-place upgrade hazards entirely, and it's a strong argument for getting onto the 9.x line if you aren't already.
Targeting Valkey 9.x: What Actually Changed
Beyond slot migration, three 9.x changes are worth knowing when your target is 9.0 or 9.1:
- Numbered databases now work in cluster mode (9.0). This isn't a breaking change - it's a capability you gain. If you previously contorted your key design to work around the old single-database limitation in cluster mode, you can simplify after upgrading.
- Per-database access control (9.1). Valkey 9.1 added numbered database-level ACLs. Nothing breaks if you don't use them, but if you're adopting them as part of the upgrade, plan the ACL rules deliberately.
-
The Lua engine became a module (9.1) - but don't over-worry it. Valkey 9.1 moved Lua into its own module. It loads automatically by default, so
EVAL,EVALSHA, the script cache, and functions all keep working out of the box; the change mainly exists to let you disable scripting or swap the interpreter. The only case to watch is a custom or stripped-down build (a minimal container image, for instance): make sure the Lua module ships alongside the server binary, or scripting will be missing.
For any major jump, still read the target version's release notes - Valkey labels each release with an upgrade urgency and lists behavioral changes - and rehearse on a canary loaded with production-like data.
Verifying Success and Rolling Back
After either path, confirm the cluster is genuinely healthy before you tear anything down: INFO replication shows the expected roles and links, CLUSTER INFO reports cluster_state:ok with all 16,384 slots owned, and your application metrics - error rates, latency, redirects - sit at baseline.