Databases

Valkey vs Redis: Key Differences and How to Migrate

If you run Redis today, you have a decision to make. Redis changed its license in 2024, a group of maintainers forked the last open-source release into Valkey under the Linux Foundation, and both now sit side by side in the Ubuntu repositories. So the real question is not “which is better” in the abstract. It is which one belongs on your servers, and how much work it takes to move if you pick the fork.

Original content from computingforgeeks.com - post 170263

This guide compares Valkey and Redis on the things that actually decide it: licensing, governance, performance, and bundled features. Then it walks through migrating a running Redis instance to Valkey on Ubuntu, including the part most articles get wrong. On current releases the obvious migration methods do not work, and there is a specific error you will hit. We reproduced all of it on a fresh install.

Current as of July 2026. Tested on Redis 8.0.5 and Valkey 9.0.4 from the Ubuntu 26.04 LTS repositories.

Why Valkey exists

The split is worth understanding because it drives the whole comparison. In March 2024 Redis Ltd. dropped the permissive BSD license and moved Redis to a dual source-available model (RSALv2 or SSPLv1). Neither is OSI-approved open source, and both restrict offering Redis as a managed service. Within days the Linux Foundation announced Valkey, forked from Redis 7.2.4, the last BSD-licensed release, with backing from AWS, Google Cloud, Oracle, Ericsson, and Snap. Valkey kept the BSD-3-Clause license and moved to vendor-neutral governance.

Then the story got more nuanced. In May 2025, Redis 8 added AGPLv3 as a third license option alongside the two source-available ones. So the newest Redis is available as OSI open source again, which is why Ubuntu ships it. The catch is that AGPLv3 is a copyleft license with a network clause, while Valkey’s BSD-3-Clause is permissive with no strings and a foundation rather than a single company steering it. That difference, not “open vs closed”, is what most teams are actually choosing between in 2026.

Valkey vs Redis at a glance

Both projects share the same 7.2 codebase ancestry, so the fundamentals are identical: the same data types, the same RESP protocol, port 6379 by default, and the same client libraries. The table below covers where they now diverge.

AttributeValkeyRedis
LicenseBSD-3-Clause (permissive, OSI)AGPLv3, RSALv2, or SSPLv1 (your choice, since Redis 8)
GovernanceLinux Foundation, vendor-neutralRedis Ltd., single vendor
OriginFork of Redis 7.2.4 (2024)Original project
Ubuntu 26.04 packagevalkey-server (universe)redis-server (universe)
Search, JSON, vector, time seriesSeparate modules (valkey-search, valkey-json)Bundled in core since Redis 8
Multithreaded I/Oio-threads, off by defaultio-threads, off by default
Protocol and clientsRESP2/RESP3, standard Redis clients workRESP2/RESP3
Drop-in for a NEW deploymentYesBaseline
Moving existing Redis 7.4+ data inLogical copy only (see below)Not applicable

Performance and features: where each one wins

Valkey has spent its independence chasing throughput. Valkey 8 reworked network handling around asynchronous I/O threads and posted a headline benchmark of roughly 1.2 million requests per second on a 16-vCPU Graviton3 instance, more than triple Valkey 7.2 on the same hardware. It also trimmed memory overhead by up to about 10 percent through more compact key storage. Valkey 9 added hash-field expiration (per-field TTLs with HEXPIRE), atomic cluster slot migrations, and further latency work. If raw scaling on big multi-core boxes is your priority, Valkey is where the recent engineering has gone.

Redis 8 answered by folding its formerly commercial modules into the open-source core. A single Redis install now ships full-text and vector Search, JSON, Time Series, the probabilistic types (Bloom, Cuckoo, Top-K), and native Vector Sets, all under the same license as the server. That is the real Redis advantage today. If you want JSON documents or vector similarity search from one package with no add-ons, Redis gives you that out of one install, whereas Valkey keeps those capabilities in separate modules you add yourself.

For a plain key-value cache or session store, which is what most deployments actually are, the two are interchangeable in day-to-day use. The threading knob is off by default on both (io-threads is set to 1), so a stock install of either behaves the same until you tune it.

Is Valkey a drop-in replacement for Redis?

For a brand-new deployment, yes. Valkey speaks RESP2 and RESP3 on the same port, accepts a Redis-style config file, and works with every mainstream client (redis-py, Jedis, Lettuce, go-redis, ioredis, StackExchange.Redis) unmodified. Valkey even reports redis_version:7.2.4 in its INFO output so version-sniffing clients keep working. Point your application at Valkey instead of Redis and nothing else changes. Our guide to installing Valkey on Ubuntu covers a clean setup.

The catch is existing data. Valkey can load RDB snapshots and AOF files from Redis 2.x through 7.2.x, but not from Redis 7.4 or later. Since current distributions ship Redis 8, that boundary is exactly where most real migrations land, and it breaks the two methods everyone reaches for first.

Migrating Redis to Valkey on Ubuntu

Ubuntu 26.04 carries both servers in the universe repository, so you can install each with a single command. Check what the repo offers:

apt-cache policy redis-server valkey-server

On a fresh 26.04 box the candidates are Redis 8 and Valkey 9:

redis-server:
  Candidate: 5:8.0.5-1
valkey-server:
  Candidate: 9.0.4-0ubuntu0.1

They use parallel layouts: Redis is redis-server/redis-cli with its config at /etc/redis/redis.conf and data in /var/lib/redis; Valkey is valkey-server/valkey-cli with /etc/valkey/valkey.conf and /var/lib/valkey. Both listen on 6379, so you cannot run them on the default port at the same time. Assume a running Redis 8 holding real data, and Valkey freshly installed alongside it.

The methods that do not work on Redis 8

The standard advice is “copy the dump.rdb” or “replicate, then promote”. Both fail on Redis 7.4+ because the on-disk and on-wire snapshot format moved to RDB version 12, which Valkey refuses to load. Copying the snapshot into Valkey’s data directory and starting the service ends in a failed unit:

sudo systemctl stop redis-server
sudo cp /var/lib/redis/dump.rdb /var/lib/valkey/dump.rdb
sudo chown valkey:valkey /var/lib/valkey/dump.rdb
sudo systemctl restart valkey-server

The service refuses to come up, and Valkey’s log names the reason exactly:

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

Replication runs into the same wall from the other direction. A full sync ships the primary’s dataset as an RDB, so pointing Valkey at Redis with REPLICAOF transfers the snapshot and then fails to load it. The replication link never comes up, and the log shows the identical message during the sync. MIGRATE, DUMP, and RESTORE are no escape either, because they use the same version-tagged serialization:

redis-cli MIGRATE 127.0.0.1 6380 user:1001 0 5000
ERR Target instance replied with error: ERR DUMP payload version or checksum are wrong

All three of the usual routes hit the same version boundary, captured here on the test box:

Redis 8 to Valkey 9 migration failing with Can't handle RDB format version 12 on Ubuntu 26.04

None of this applies if your source is Redis 7.2 or older. There the RDB copy and the replication route both work, and the Valkey migration docs list them as the supported paths. The wall is specific to the 7.4-and-later snapshot format, which is what you get from any current distribution.

The logical migration that works

The way through is to move data at the command layer instead of the file layer. Read every key from Redis with normal commands and write it back into Valkey with normal commands. That path is version-independent because it never touches the RDB serialization. A short Python script using the standard client does it cleanly. Install the client first:

sudo apt install -y python3-redis

Run Valkey on a temporary port so both servers are up at once. Edit its config:

sudo sed -i 's/^port 6379/port 6380/' /etc/valkey/valkey.conf
sudo systemctl restart valkey-server

Create the migration script. It scans the source database, copies each key according to its type, and preserves any TTL:

vim migrate-redis-to-valkey.py

Add the following:

#!/usr/bin/env python3
"""Type-aware logical migration from Redis to Valkey.
Works across incompatible RDB versions (Redis 7.4+/8.x -> Valkey), where
copying dump.rdb or REPLICAOF both fail. Copies keys via the command
layer and preserves TTLs.
"""
import redis

SRC = redis.Redis(host="127.0.0.1", port=6379, db=0)          # Redis
DST = redis.Redis(host="127.0.0.1", port=6380, db=0)          # Valkey

moved = skipped = 0
for key in SRC.scan_iter(count=500):
    ktype = SRC.type(key).decode()
    if ktype == "string":
        DST.set(key, SRC.get(key))
    elif ktype == "hash":
        DST.hset(key, mapping=SRC.hgetall(key))
    elif ktype == "list":
        DST.rpush(key, *SRC.lrange(key, 0, -1))
    elif ktype == "set":
        DST.sadd(key, *SRC.smembers(key))
    elif ktype == "zset":
        DST.zadd(key, dict(SRC.zrange(key, 0, -1, withscores=True)))
    else:
        skipped += 1
        print(f"  skipped unsupported type {ktype}: {key.decode()}")
        continue
    pttl = SRC.pttl(key)          # ms remaining, -1 = no expiry
    if pttl and pttl > 0:
        DST.pexpire(key, pttl)
    moved += 1

print(f"migrated={moved} skipped={skipped} target_dbsize={DST.dbsize()}")

Run it against the live pair:

python3 migrate-redis-to-valkey.py

Every key transfers and the target key count matches the source:

migrated=11 skipped=0 target_dbsize=11

Spot-check the data in Valkey. Types and TTLs come across intact, so a hash is still a hash and a key that had 26 seconds left still expires on schedule:

Logical Redis to Valkey migration script moving 11 keys with types and TTL preserved on Ubuntu 26.04

This script is deliberately minimal so it stays readable, and it copies logical database 0 only. If your keys live in other databases, loop the same logic over each one. For very large datasets, a purpose-built tool such as RIOT (Redis Input/Output Tools) runs the transfer with batching and progress reporting. Use its data-structure mode (riot replicate --struct), because RIOT’s default mode uses the same DUMP and RESTORE serialization that fails across this version boundary. Note that RIOT is now archived and read-only, superseded by the closed-source RIOT-X, though the Apache-licensed release still works.

Cut over to Valkey

With the data in place, stop Redis, move Valkey back to the default port, and repoint your application. Because Valkey answers as a Redis-compatible server, the application does not know the difference:

sudo systemctl disable --now redis-server
sudo sed -i 's/^port 6380/port 6379/' /etc/valkey/valkey.conf
sudo systemctl restart valkey-server

Confirm Valkey is serving on 6379 with your data and the compatibility version string clients expect:

Valkey 9.0.4 serving on port 6379 after migrating from Redis on Ubuntu 26.04

From here the operational habits carry over unchanged. If you scrape metrics, the same exporter works, and our guide on monitoring Valkey with Prometheus and Grafana picks up where this leaves off. The steps are identical on other distributions too, with Valkey on Rocky and AlmaLinux and Valkey on Debian covering the package differences.

Which one should you run?

For most teams running a cache, a queue, or a session store, Valkey is the easy pick: it is permissively licensed, foundation-governed, backed by the major clouds, and it is where the throughput and memory work is happening. That is also why the cloud providers standardized on it. If you are starting fresh, install Valkey and move on.

Redis earns its place when you lean on the bundled capabilities. If your workload needs JSON documents, full-text search, or vector similarity from a single install, Redis 8 delivers that in core, and AGPLv3 is workable for plenty of internal deployments. Weigh the copyleft network clause against your distribution model before you commit. If you already run Redis and simply want the open-source cache without the licensing questions, the migration above is a couple of hours of work, and the only real surprise, the RDB version wall, is now behind you. Either way, keep a tested backup and run the switch in a staging environment before production. Our Redis on Ubuntu install guide is the reference if you need to stand up a source instance to practice against.

Keep reading

Configure Windows Server 2022/2025 Failover Clustering Databases Configure Windows Server 2022/2025 Failover Clustering Install SQL Server Management Studio on Windows Databases Install SQL Server Management Studio on Windows Install DBeaver on Ubuntu 24.04 and Debian 13 Databases Install DBeaver on Ubuntu 24.04 and Debian 13 ProxySQL Read/Write Split for MySQL: Query Rules and Hostgroups Databases ProxySQL Read/Write Split for MySQL: Query Rules and Hostgroups MySQL High Availability: Percona XtraDB Cluster with ProxySQL Databases MySQL High Availability: Percona XtraDB Cluster with ProxySQL Install MariaDB 12.0 on Rocky Linux 10 / AlmaLinux 10 AlmaLinux Install MariaDB 12.0 on Rocky Linux 10 / AlmaLinux 10

Leave a Comment

Press ESC to close