Valkey: Set up replication for Valkey

Some time ago, I wrote about Valkey as an alternative for Redis (see here). And in fact, many companies are using it in production.
But installing Valkey in Docker or on a server isn't enough, as there should be any mechanism for high availability.
So I'll give a short info on how to do that:
Primary server
Your primary server should already be installed. Just log into it usingvalkey-cli
:
# valkey-cli
127.0.0.1:6379>
Let's see if it's in primary mode:
127.0.0.1:6379> ROLE
1) "master"
2) (integer) 568634
3) (empty array)
Replica server(s)
Installing Valkey on additional servers is very easy - either use Docker, or any other Containerization, or even just a native or virtualized server.
On Linux, I just run
# apt -y install valkey-server
or
# dnf -y install valkey-server
On most systems, the server will be integrated in systemd
and also started.
As these Valkey servers are installed without authentication, we can easily login to it:
# valkey-cli
Then we execute the role
command:
127.0.0.1:6379> role
1) "master"
2) (integer) 0
3) (empty array)
Now we set up this Valkey installation to be a replication slave:
127.0.0.1:6379> REPLICAOF <primary server> 6379
OK
In the log files of the primary server, we can see what happens:
db-1 | 1:M 11 Oct 2025 10:34:23.824 * Replica <replica server>:6379 asks for synchronization
db-1 | 1:M 11 Oct 2025 10:34:23.824 * Partial resynchronization not accepted: Replication ID mismatch (Replica asked for '<id1>', my replication IDs are '<id2>' and '0000000000000000000000000000000000000000')
db-1 | 1:M 11 Oct 2025 10:34:23.824 * Replication backlog created, my new replication IDs are '<id3>' and '0000000000000000000000000000000000000000'
db-1 | 1:M 11 Oct 2025 10:34:23.824 * Delay next BGSAVE for diskless SYNC
db-1 | 1:M 11 Oct 2025 10:34:28.409 * Starting BGSAVE for SYNC with target: replicas sockets using: normal sync
db-1 | 1:M 11 Oct 2025 10:34:28.412 * Background RDB transfer started by pid 17 to pipe through parent process
db-1 | 17:C 11 Oct 2025 10:34:28.419 * Fork CoW for RDB: current 0 MB, peak 0 MB, average 0 MB
db-1 | 1:M 11 Oct 2025 10:34:28.420 * Diskless rdb transfer, done reading from pipe, 1 replicas still up.
db-1 | 1:M 11 Oct 2025 10:34:28.433 * Background RDB transfer terminated with success
db-1 | 1:M 11 Oct 2025 10:34:28.434 * Streamed RDB transfer with replica <replica server>:6379 succeeded (socket). Waiting for REPLCONF ACK from replica to enable streaming
db-1 | 1:M 11 Oct 2025 10:34:28.434 * Synchronization with replica <replica server>:6379 succeeded
Check configuration
We can see that the new replica server asks to be integrated into replication. Primary server finds out that he doesn't know it yet, so a partial resync would not be successful. So it creates a backup on primary site, transfers it to the replication site, and starts replication.
On primary site, we can check the status:
# valkey-cli
127.0.0.1:6379> role
1) "master"
2) (integer) 568634
3) 1) 1) "<replica node>"
2) "6379"
3) "568634"
But does it really replicate data? It's easy to check that:
- Check that value does not exist on replica:
127.0.0.1:6379> GET key_one
(nil)
- Insert data
127.0.0.1:6379> SET key_one value_one
OK
- Check that data exists in primary node:
127.0.0.1:6379> GET key_one
"value_one"
- Check that data exists in replica node:
127.0.0.1:6379> GET key_one
"value_one"
Usage
Valkey does not have routing for read only operations, so if you want to use your replicas for read only operations, you'd have to create connections to it manually.
Failover
By default, Valkey does not have an integrated failover mechanism. So we have to do it on our own:
- (old) Replica server
# valkey-cli
127.0.0.1:6379> REPLICAOF NO ONE
OK
This disables the replication on the old replica and makes it a primary.
- (old) Primary server
# valkey-cli
127.0.0.1:6379> REPLICAOF <old replica server> 6379
OK
This enables the replication on the old primary server and makes it the new replica.
After that, we can check again the status (from the new primary node):
# valkey-cli
127.0.0.1:6379> role
1) "master"
2) (integer) 568634
3) 1) 1) "<new replica node>"
2) "6379"
3) "568634"
If you prefer automatic failover, you'd have to use Valkey Sentinel for that. I'll discuss that in another post...