How to Migrate Redis to Valkey on Ubuntu 26.04

Deepak Prasad
Tested on Ubuntu 26.04 LTS (Resolute Raccoon)
Package redis-server 5:8.0.5-1
valkey-server 9.0.4-0ubuntu0.2
valkey-tools 9.0.4-0ubuntu0.2
Applies to Ubuntu 26.04 (primary); short note for 24.04 valkey-redis-compat
Privilege sudo or root for package and service changes
Scope Show why Redis 8 dumps fail on Valkey 9, why valkey-redis-compat is gone, run a side-by-side logical cutover for a small text fixture, and verify every migrated type. Does not cover Redis Cluster, Redis Enterprise, or a full RedisShake tutorial.
Related guides Install Redis on Rocky Linux 9
Short on time?Beta Get the gist of this 12-minute read in seconds, then ask follow-up questions

Ubuntu 26.04 ships both Redis 8 and Valkey 9, but their persistence formats are no longer directly compatible. Redis 8 dump files use RDB format version 12, which Valkey 9 rejects, so a blind copy of dump.rdb fails. Canonical removed valkey-redis-compat once Redis moved to 8.0 because Valkey was no longer a drop-in replacement.

This guide stays on Ubuntu 26.04: prove the RDB and DUMP failures, reseed a small text-only fixture beside Redis, cut over to valkey-server, and verify string, hash, list, set, and TTL. For real datasets, use a purpose-built logical migration tool rather than a shell script.


Which Ubuntu Version Am I On?

Confirm the release before you pick a path. Use check Ubuntu version (lsb_release, /etc/os-release, or the GUI) if you are unsure which Ubuntu you are on.

Ubuntu Typical path
24.04 LTS Check for valkey-redis-compat first (see the short note below)
25.10 / 26.04 Compatibility package removed; Redis 8 persistence is not a drop-in for Valkey

If you are still on 24.04 with Redis 7.x, do not follow the full 26.04 cutover until you have checked whether valkey-redis-compat is available.


Quick Answer: Redis 8 to Valkey on Ubuntu 26.04

On Ubuntu 26.04, install Valkey beside Redis, keep Redis on port 6379, recreate the dataset logically into a temporary Valkey instance, write a Valkey-native RDB, then cut over the packaged valkey-server to 6379. Do not treat a Redis 8 dump.rdb as a drop-in file for Valkey.

Install the packages:

bash
sudo apt install valkey-server valkey-tools

A common wrong turn is copying the Redis dump into Valkey’s data directory:

bash
sudo cp /var/lib/redis/dump.rdb /var/lib/valkey/dump.rdb

That copy can succeed as a file operation, but Valkey exits when it tries to load Redis 8’s RDB format version 12:

output
Can't handle RDB format version 12
Fatal error loading the DB, check server logs. Exiting.

Use the logical path instead: keep Redis on 6379, run a temporary Valkey on another port, reconstruct keys with a migration tool (or the small text-only demo later), write a Valkey-native RDB, stop Redis, place that dump under /var/lib/valkey, then enable valkey-server on 6379.

  ┌──────────────┐   logical recreate    ┌────────────────────┐
  │ Redis :6379  │ ─────────────────────► │ Temp Valkey :6380  │
  │ (Redis 8)    │                        │ /var/tmp/…         │
  └──────────────┘                        └─────────┬──────────┘
                                                    │ SAVE
                                                    ▼
                                          ┌────────────────────┐
  Stop redis-server                       │ Valkey-native RDB  │
  Place dump → /var/lib/valkey            └─────────┬──────────┘
                                                    ▼
                                          ┌────────────────────┐
                                          │ valkey-server:6379 │
                                          └────────────────────┘

Check Redis and Valkey Packages

Inspect candidates with apt. For package candidate details, apt-cache policy is covered in the apt-cache command guide:

bash
apt-cache policy redis-server valkey-server valkey-redis-compat
output
redis-server:
  Installed: 5:8.0.5-1
  Candidate: 5:8.0.5-1
  Version table:
 *** 5:8.0.5-1 500
        500 http://in.archive.ubuntu.com/ubuntu resolute/universe amd64 Packages
valkey-server:
  Installed: 9.0.4-0ubuntu0.2
  Candidate: 9.0.4-0ubuntu0.2
  Version table:
 *** 9.0.4-0ubuntu0.2 500
        500 http://in.archive.ubuntu.com/ubuntu resolute-updates/main amd64 Packages

valkey-redis-compat has no candidate on Ubuntu 26.04. On Ubuntu 24.04 (Noble) that package still exists in universe and depends on valkey-server. Use it only on releases that still ship it.


Why File-Based Migration Fails on Ubuntu 26.04

Upstream Valkey documents compatibility with Redis OSS through 7.2. Redis 7.4+ and Redis 8 produce dumps Valkey cannot load.

I pointed Valkey at a Redis 8 data file. The process exited and the log showed:

text
Can't handle RDB format version 12
Fatal error loading the DB, check server logs. Exiting.

DUMP + RESTORE does not bypass that boundary either. DUMP uses Redis’ internal serialized value format, and RESTORE checks the embedded format version and checksum. On this host the restore side returned:

text
-ERR DUMP payload version or checksum are wrong

Because direct RDB and DUMP transfer cross an incompatible serialization boundary, use a logical migration method that reads data through Redis commands and recreates it in Valkey. For real workloads, use a purpose-built tool (the Valkey migration guide mentions options such as RIOT, RedisShake, and Redis-Migrate-Tool). RedisShake currently documents Redis 2.8–8.x and Valkey 8.x/9.x coverage, which matches this Ubuntu 26.04 pair well. The small Bash example later demonstrates the idea only for the text fixture in this article.


Note on Ubuntu 24.04 and valkey-redis-compat

On Ubuntu 24.04, valkey-redis-compat is described as a conversion script and compatibility symlinks for Redis. Canonical’s packaging could migrate configuration and data and create /etc/valkey/REDIS_MIGRATION so Valkey does not auto-start until you verify the result, then remove that marker and start the service.

On Ubuntu 24.04, check the valkey-redis-compat package and Canonical's migration workflow first; it may provide the distro-supported migration path for that release. On 26.04 the package is gone (Launchpad tracked removing it after Redis 8 broke drop-in migration).


Install Redis and Capture Baseline Data

If Redis is not installed yet, follow Install Redis on Ubuntu or install it here:

bash
sudo apt install redis-server

Enable and start Redis with systemctl:

bash
sudo systemctl enable --now redis-server

Confirm Redis answers:

bash
redis-cli PING
output
PONG

Redis is up. Create the text-only fixture you will verify after cutover. Store a string:

bash
redis-cli SET glc:string "hello-redis"

SET returns OK. Add a hash:

bash
redis-cli HSET glc:hash field1 value1 field2 value2

Clear and fill a list:

bash
redis-cli DEL glc:list

DEL returns how many keys were removed. Push three list elements:

bash
redis-cli LPUSH glc:list a b c

LPUSH returns the list length. Add a set:

bash
redis-cli SADD glc:set x y z

SADD returns how many members were added. Store a key with a one-hour TTL:

bash
redis-cli SET glc:ttl expires EX 3600

Check how many keys exist:

bash
redis-cli DBSIZE
output
5

Five keys means the fixture is ready. Create a Redis snapshot for backup (Valkey cannot load this Redis 8 file directly):

bash
redis-cli SAVE
output
OK

Confirm the dump path:

bash
ls -l /var/lib/redis/dump.rdb
output
-rw-rw---- 1 redis redis 244 Sep 22 07:48 /var/lib/redis/dump.rdb

The file is owned by redis and ready to archive as a backup. Keep a copy of /etc/redis/redis.conf as well.


Install Valkey Beside Redis

Install the server and CLI packages:

bash
sudo apt install valkey-server valkey-tools

apt installs both packages without removing Redis. They both default to port 6379, so only one service should own that port during cutover.

Because Redis already owns port 6379, the packaged Valkey service may be stopped or may fail its first automatic start. That is expected during this side-by-side migration; the temporary Valkey instance below will use port 6380.

Stop the packaged Valkey unit so the migration state is deterministic:

bash
sudo systemctl stop valkey-server

With the packaged unit stopped, Redis remains the only listener on 6379 while you work on port 6380.

Item Redis Valkey
Packages redis-server, redis-tools valkey-server, valkey-tools
CLI redis-cli valkey-cli
systemd unit redis-server.service (redis.service alias) valkey-server.service (valkey.service alias)
Config /etc/redis/redis.conf /etc/valkey/valkey.conf
Data dir /var/lib/redis /var/lib/valkey

Logical Reseed Demo (Text Fixture Only)

IMPORTANT
The Bash copy_key function below is a small text-only demonstration. It is not a general production migration tool. Binary values, embedded newlines, NUL bytes, large values, sorted sets, streams, HyperLogLog, geospatial keys, modules, multiple logical databases, and concurrent writes all need a purpose-built migrator such as RedisShake or RIOT. This demo also assumes the fixture is not changing while it is copied. A live production dataset needs a migration tool and a consistency/cutover strategy.

Keep Redis on 6379. Use a directory with enough free space for your dataset. This lab uses /var/tmp/valkey-migration instead of /tmp. Create it owned by the valkey user so the temporary daemon does not run as root:

bash
sudo install -d -o valkey -g valkey /var/tmp/valkey-migration

Start a temporary Valkey on port 6380 as the valkey user, bound to localhost (protected mode stays on):

bash
sudo -u valkey valkey-server --port 6380 --daemonize yes --dir /var/tmp/valkey-migration --dbfilename dump.rdb --bind 127.0.0.1 --appendonly no

Daemonized Valkey returns to the shell with no banner when it starts. Confirm the temporary instance answers:

bash
valkey-cli -p 6380 PING
output
PONG

Port 6380 is ready. For this fixture only, copy each key by Redis type:

bash
copy_key() {
  key="$1"
  t=$(redis-cli TYPE "$key")
  ttl=$(redis-cli PTTL "$key")
  case "$t" in
    string)
      val=$(redis-cli --raw GET "$key")
      valkey-cli -p 6380 SET "$key" "$val" >/dev/null
      ;;
    hash)
      redis-cli HGETALL "$key" | {
        args=()
        while IFS= read -r field; do
          IFS= read -r value || break
          args+=("$field" "$value")
        done
        valkey-cli -p 6380 HSET "$key" "${args[@]}" >/dev/null
      }
      ;;
    list)
      redis-cli LRANGE "$key" 0 -1 | while IFS= read -r item; do
        valkey-cli -p 6380 RPUSH "$key" "$item" >/dev/null
      done
      ;;
    set)
      redis-cli SMEMBERS "$key" | while IFS= read -r member; do
        valkey-cli -p 6380 SADD "$key" "$member" >/dev/null
      done
      ;;
    *)
      echo "skip unsupported type $t for $key" >&2
      return 0
      ;;
  esac
  if [ "$ttl" -gt 0 ]; then
    valkey-cli -p 6380 PEXPIRE "$key" "$ttl" >/dev/null
  fi
  echo "copied $key ($t)"
}

redis-cli --scan | while read -r k; do copy_key "$k"; done

The five fixture keys printed copied … lines for string, hash, list, and set. Sorted sets, streams, and modules are out of scope for this demo. The demo reapplies the remaining TTL after copying the value, so expiration timing is approximate rather than bit-for-bit identical.

Verify every type on port 6380:

bash
valkey-cli -p 6380 GET glc:string
output
hello-redis

The string survived the typed copy. Confirm the hash:

bash
valkey-cli -p 6380 HGETALL glc:hash
output
field1
value1
field2
value2

Read the list:

bash
valkey-cli -p 6380 LRANGE glc:list 0 -1
output
c
b
a

Read the set:

bash
valkey-cli -p 6380 SMEMBERS glc:set
output
x
y
z

The order of SMEMBERS output is not guaranteed; verify that the same members are present rather than expecting the same order.

Check the TTL:

bash
valkey-cli -p 6380 TTL glc:ttl
output
3353

A positive TTL means the expiry was reapplied. Check the key count:

bash
valkey-cli -p 6380 DBSIZE
output
5

Five keys match the Redis fixture. Write a Valkey-native dump with synchronous SAVE:

bash
valkey-cli -p 6380 SAVE
output
OK

OK means the dump under /var/tmp/valkey-migration is complete. This snapshot is written by Valkey itself, so it uses a Valkey-compatible persistence format and can be loaded by the packaged Valkey service. Shut down the temporary process:

bash
valkey-cli -p 6380 SHUTDOWN

SHUTDOWN stops the temporary listener. Confirm the dump file:

bash
ls -l /var/tmp/valkey-migration/dump.rdb
output
-rw-r--r-- 1 valkey valkey 245 Sep 22 07:52 /var/tmp/valkey-migration/dump.rdb

Cut Over to valkey-server on Port 6379

Stop Redis so it releases the port:

bash
sudo systemctl stop redis-server

Port 6379 is free. Install the Valkey dump into the packaged data directory:

bash
sudo install -o valkey -g valkey -m 660 /var/tmp/valkey-migration/dump.rdb /var/lib/valkey/dump.rdb

install places the dump with the valkey owner and mode 660. Leave AOF off for the first load if your packaged config has it enabled:

bash
grep -E '^[[:space:]]*appendonly' /etc/valkey/valkey.conf
output
appendonly no

Start the systemd unit:

bash
sudo systemctl enable --now valkey-server

Ping the packaged service on port 6379:

bash
valkey-cli PING
output
PONG

Packaged Valkey is answering. Verify the full fixture again. Read the string:

bash
valkey-cli GET glc:string
output
hello-redis

Confirm the hash:

bash
valkey-cli HGETALL glc:hash
output
field1
value1
field2
value2

Read the list:

bash
valkey-cli LRANGE glc:list 0 -1
output
c
b
a

Read the set:

bash
valkey-cli SMEMBERS glc:set
output
x
y
z

The order of SMEMBERS output is not guaranteed; confirm the same members exist rather than matching line order.

Check the TTL:

bash
valkey-cli TTL glc:ttl
output
3333

Confirm the key count:

bash
valkey-cli DBSIZE
output
5

Five keys and a positive TTL confirm the cutover preserved the fixture.

Before you disable Redis, point or restart the application against Valkey and confirm one critical read/write path. Protocol compatibility does not guarantee every Redis 8 feature has a Valkey equivalent.

When the application smoke test passes, disable Redis so it does not fight for 6379 after reboot:

bash
sudo systemctl disable redis-server

disable keeps the package installed but stops Redis from starting at boot. Merge any custom settings from /etc/redis/redis.conf into /etc/valkey/valkey.conf (bind, passwords, maxmemory, persistence), then restart Valkey if you changed the file. Do not uninstall Redis immediately.


Rollback If the Cutover Fails

Keep Redis stopped (not removed), keep the original Redis RDB and config, and keep the application endpoint easy to retarget.

To roll back while port 6379 is free and Redis data is intact:

bash
sudo systemctl stop valkey-server

Start Redis again:

bash
sudo systemctl start redis-server

Confirm Redis answers with redis-cli PING, then point the application back at Redis. This simple rollback is valid only while no new writes have occurred exclusively on Valkey. If applications have already changed data after cutover, reconcile those writes before switching back.


Update Application References

Old New
redis-server.service / redis.service valkey-server.service / valkey.service
redis-cli valkey-cli (or keep redis-cli only while Redis tools remain installed)
/etc/redis/redis.conf /etc/valkey/valkey.conf
/var/lib/redis /var/lib/valkey

Client libraries can usually keep using host 127.0.0.1 and port 6379. Retest AUTH and TLS.


Common Migration Problems

Symptom Likely cause Fix
Can't handle RDB format version 12 Redis 8 dump copied into Valkey Use logical/tool migration; do not copy that RDB
DUMP payload version or checksum are wrong Redis 8 serialization vs Valkey restore Use a logical migrator, not DUMP/RESTORE
valkey-redis-compat has no installation candidate Package removed on Ubuntu 26.04 Use logical/tool path; on 24.04 use the compat package if present
Both services fail on start Both bound to 6379 Run only one on that port during cutover
Empty Valkey after cutover Wrong dump path, ownership, or AOF on first start Confirm /var/lib/valkey/dump.rdb ownership and appendonly no

Summary

On Ubuntu 26.04, Redis 8 and Valkey 9 both install, but Redis 8 RDB files and DUMP payloads are not loadable by Valkey 9, and valkey-redis-compat is gone. Prove the failure, keep Redis online, recreate data logically with a real migration tool for production datasets (or the text-only demo for a tiny fixture), write a Valkey-native dump, stop Redis, place the dump under /var/lib/valkey, and enable valkey-server only after an application smoke test.

On Ubuntu 24.04, check valkey-redis-compat first. If you are on RHEL 10 instead, Redis is gone from the repositories entirely; use Redis removed on RHEL 10: migrate to Valkey.


References


Frequently Asked Questions

Can I copy dump.rdb from Redis 8 to Valkey on Ubuntu 26.04?

No. Valkey 9 rejects RDB format version 12 with a fatal load error. Use a logical key copy or a migration tool instead.

Is valkey-redis-compat available on Ubuntu 26.04?

No. It was important on Ubuntu 24.04 and was removed for later releases after Redis 8 broke drop-in migration.

Do Redis and Valkey conflict as packages?

They can install side by side, but both default to port 6379. Only one service should listen there.

Can redis-cli talk to Valkey?

Yes for common commands while redis-tools remains installed. Prefer valkey-cli on the Valkey host going forward.

Is the Bash copy_key script safe for production?

No. It is only a text-fixture demonstration. Use a purpose-built logical migration tool for real datasets.

Finished reading?Beta Get the key takeaways in seconds, then ask follow-up questions
Omer Cakmak

Linux Administrator

Highly skilled at managing Debian, Ubuntu, CentOS, Oracle Linux, and Red Hat servers. Proficient in bash scripting, Ansible, and AWX central server management, he handles server operations on OpenStack, KVM, Proxmox, and VMware.

  • Debian
  • Ubuntu
  • Linux
  • Red Hat Enterprise Linux
  • Shell Script
  • System Administration