Migrating from Redis to Valkey in Java: A Complete Guide
Valkey was forked from Redis OSS 7.2.4 and remains wire- and command-compatible with it. For a Java application, that means migrating is an infrastructure change rather than a code change — provided your client supports both engines. In the common case you are editing a connection string, not rewriting a data layer.
The work that remains is real, though, and it is not where most teams expect. It is not the protocol, the commands or the data structures. It is module dependencies, serialization codecs and cutover mechanics. This guide covers all three, along with the migration paths for each deployment topology.
Why Java Teams Are Moving to Valkey
Almost always, the trigger is licensing rather than technology.
How the licence changed, twice
Every Redis release up to and including 7.2.4 shipped under the permissive BSD 3-Clause licence. In March 2024, Redis Ltd. announced that from version 7.4 the software would ship under a dual model — the Redis Source Available License v2 (RSALv2) and the Server Side Public License v1 (SSPLv1) — neither of which is OSI-approved. Within days the Linux Foundation forked Redis OSS 7.2.4 as Valkey, retaining the BSD licence, with backing from AWS, Google Cloud, Oracle, Ericsson and Snap.
In May 2025 Redis 8.0 added AGPLv3 as a third option, so Redis is once again open source by the OSI definition. That is worth stating plainly, because a lot of migration advice written in 2024 assumes it is not.
Why AGPLv3 is still a blocker
AGPLv3 is strong copyleft: modify the source, run it as a network service, and you may be obliged to publish your modifications. In practice, ordinary use of an unmodified data store rarely triggers those obligations. That is not the point. Many enterprises maintain blanket policies prohibiting AGPL-licensed dependencies anywhere in the stack, because legal teams are wary of the copyleft reach rather than the specific facts of any one deployment.
The result is that the decision is frequently made by procurement or legal, and lands on an engineering team as a requirement rather than a question. If that is your situation, the rest of this guide is the practical part.
What you gain on arrival
Valkey has not stood still since the fork. Valkey 8.0 introduced asynchronous I/O threading and a per-slot dictionary that cuts roughly 16 bytes of overhead per key-value pair. Valkey 9.0 added hash field expiration, multi-database support in cluster mode, SIMD acceleration across several hot paths, and — per AWS — up to 40% higher throughput on pipelined workloads. Valkey 9.1.1 is the current stable release as of July 2026, with the 9.1, 9.0, 8.1, 8.0 and 7.2 lines all actively maintained.
Several newer commands are directly useful during a migration, and are covered in the paths below.
What Changes for Your Java Application, and What Doesn't
The RESP protocol is unchanged. The core command surface is unchanged. Core data types behave identically. What determines your migration path is how far past the 7.2.4 fork point you have drifted.
| Your current Redis | Recommended target | Java code changes | Watch out for |
|---|---|---|---|
| Redis 7.2.4 or earlier | Valkey 9.1 | None | Nothing. Valkey forked from exactly here, so this is effectively an upgrade |
| Redis 7.4.x | Valkey 9.1 | None expected | Hash field TTL arrived in Redis 7.4 and Valkey 8.1. Fine on 9.1, breaks if you target Valkey 8.0 |
| Redis 8.0–8.8 | Valkey 9.1 | None for core | Redis 8 folded the Stack modules into core. You may have picked up dependencies without logging them. Redis 8.8's Array type and INCREX have no Valkey equivalent |
| Redis Stack, any version | Valkey 9.1 plus modules | Depends | This is where the real work is. See the module section below |
| Redis Enterprise or Redis Cloud | Managed or self-managed Valkey | Possible | Redis Enterprise's Active-Active CRDB, which is multi-master with conflict-free replicated types, has no open-source Valkey equivalent. Some managed Valkey services do offer native cross-region replication, so check your target before assuming the capability is gone |
| ElastiCache for Redis OSS | ElastiCache for Valkey 9.0 | None | In-place engine change. AWS lists Valkey as the recommended ElastiCache engine and prices it 20% below Redis OSS on node-based clusters |
| MemoryDB for Redis | MemoryDB for Valkey | None | MemoryDB is durable by design; ElastiCache added opt-in durability only from Valkey 9.0. Confirm which model your target uses rather than reusing an existing runbook |
| Memorystore for Redis | Memorystore for Valkey 9.0 | None | A separate product, so a new instance rather than an in-place upgrade — but Google provides migration support and lets you carry committed use discounts across |
| Azure Cache for Redis | Self-managed Valkey, typically on AKS | None | No first-party Azure Valkey service. Note also that Azure Cache for Redis is being retired — Enterprise tiers on 31 March 2027, Basic/Standard/Premium on 30 September 2028 — so you face a migration regardless |
Java client support
The Valkey project lists three recommended Java clients: Redisson, Valkey GLIDE and valkey-java. Other clients that support Redis OSS 7.2 will generally connect, since the wire protocol is shared, but they are not part of the tested set.
Redisson supports Valkey deployments from 7.2.5 through current releases and accepts the valkey://, valkeys:// (TLS) and valkey+uds:// (Unix domain socket) URL schemes alongside the traditional redis:// forms. Because the same client, the same API and the same objects work against both engines, the engine choice never reaches your application code — and a rollback is a configuration revert rather than a redeployment.
Pre-Migration Checklist
Complete this before choosing a path. Most migrations that go badly go badly because something on this list was discovered during the cutover instead of before it.
- Topology — standalone, Sentinel, Cluster or managed
- Redis version — determines your row in the table above
- Modules — run
MODULE LISTagainst every primary node. Do this first; it is the most common source of surprises - Lua scripts — inventory every
EVALandFUNCTIONyou depend on, including those your client issues on your behalf - Persistence — RDB, AOF or both, and the current file versions
- Auth and ACLs — users, rules, and whether you use TLS
- Client library and version — pin it, and read the next section on codecs before you upgrade it
- Serialization codec — the single most dangerous item on this list
- Baseline metrics — key count, memory footprint, p99 latency. You cannot verify a migration without a before
Choose Your Migration Path
| Path | Downtime | Rollback | Best for |
|---|---|---|---|
| A — Standalone, snapshot copy | Brief pause | Simple | Small datasets, tolerant workloads |
| A — Standalone, live replication | None | Simple | Anything write-heavy |
| B — Sentinel | Failover only | Moderate | Existing HA deployments |
| C — Cluster | None | Moderate | Sharded production estates |
| D — Managed service | Provider-dependent | Varies | ElastiCache, MemoryDB, Memorystore |
Path A: standalone Redis to Valkey
Two options. The simplest is a snapshot copy: disconnect active connections, take a fresh RDB with BGSAVE, copy the file to the Valkey host and start Valkey against it. Valkey loads the snapshot on startup. The trade-off is downtime while Valkey loads, plus a risk of losing writes on a busy instance if connections are not fully drained.
The lower-risk option is live replication: configure the Valkey instance as a replica of the Redis primary with REPLICAOF, let it sync, then promote it and repoint clients. Valkey also provides CLIENT IMPORT-SOURCE, which marks a connection as an import source while the server is in import mode. If you are driving the copy with a migration tool rather than with replication, check whether it supports this.
Path B: Redis Sentinel to Valkey Sentinel
Add Valkey replicas to the existing Sentinel-monitored set, allow them to sync, then trigger a failover so a Valkey node becomes primary. Retire the Redis nodes once the topology is stable. The one detail teams routinely miss: masterName is configured on the Sentinel side, and a mismatch between it and your client configuration is a silent failure at cutover, not a startup error.
Path C: Redis Cluster to Valkey Cluster
Add Valkey nodes to the existing cluster as replicas, wait for replication to complete, then promote one Valkey replica per Redis primary. No downtime is required. Note that this path runs on replication and failover, not slot movement — the mixed Redis and Valkey cluster you have mid-migration cannot use Valkey-specific cluster commands. Once you are fully on Valkey, resharding gets easier: CLUSTER MIGRATESLOTS performs atomic slot migration, with CLUSTER GETSLOTMIGRATIONS for observable progress and CLUSTER CANCELSLOTMIGRATIONS to abort. That is a capability you gain on arrival rather than a tool for the crossing.
This path has enough operational detail to deserve its own treatment. We cover it step by step in Migrating Your Java App from Redis Cluster to Valkey Cluster, and the related mechanics in How to Upgrade a Valkey Cluster With Zero Downtime.
Path D: managed services
On AWS, moving ElastiCache or MemoryDB to Valkey is an engine change handled by the provider, and AWS lists Valkey as its recommended ElastiCache engine. There is usually a cost argument alongside the licensing one: AWS prices Valkey 20% below other supported engines on node-based clusters and 33% below on Serverless, which on a mid-sized production cluster is a line item large enough to get the migration approved on its own. Memorystore for Valkey 9.0 is generally available. It is a separate product from Memorystore for Redis, so this is a new instance rather than an in-place upgrade, but Google provides migration support and lets you reuse existing committed use discounts. One detail that matters if you are coming from standalone Redis: Memorystore for Valkey can run with cluster mode disabled, which lets you move engines without also being forced into a cluster topology. You give up sharding and are capped at two replicas, but the application impact is far smaller. Azure has no first-party Valkey service, so the realistic route is self-managed Valkey on AKS.
Migrating the Java Layer with Redisson
Step 1: repoint the client
This is the entire application-side change for most deployments:
singleServerConfig:
address: "valkey://valkey-host:6379"
The same applies across topologies. Cluster mode:
Config config = new Config();
config.useClusterServers()
.setScanInterval(1000)
.addNodeAddress(
"valkey://valkey-node-1:6379",
"valkey://valkey-node-2:6379",
"valkey://valkey-node-3:6379");
RedissonClient redisson = Redisson.create(config);
You only need to seed a subset of nodes — Redisson discovers the rest and refreshes topology on scanInterval, which matters during a migration precisely because nodes are being added and promoted while the client is live. Sentinel mode uses useSentinelServers() with setMasterName(); managed services use useReplicatedServers(), almost always with the TLS valkeys:// scheme, since managed Valkey generally enforces in-transit encryption.
Two version notes. Redisson added a database setting for Valkey Cluster mode in 4.0.0, matching Valkey 9.0's multi-database support. More importantly, use Redisson 4.3.1 or later if you are migrating on AWS — that release fixed a bug where the master connection could freeze during an ElastiCache Valkey upgrade, which is exactly the operation you are about to perform.
Step 2: swap the client, if you are not already on Redisson
If you are coming from Spring Data Redis, Redisson supplies a connection factory that plugs into Spring's RedisConnectionFactory abstraction, so existing RedisTemplate wiring is preserved rather than rewritten. Check the current class and module against the version you are pinning — Redisson reorganised its Spring modules during the 4.x line. We have dedicated guides for Jedis, Lettuce, Spring Data Redis and Valkey GLIDE.
On Spring Boot property keys, one clarification that causes repeated confusion: Redisson's own prefix is spring.redis.redisson.* and has not changed. What changed is Spring Boot's own connection properties, which moved from spring.redis.* to spring.data.redis.* in Spring Boot 3.0. Redisson resolves those reflectively so the starter tolerates multiple Boot versions.
Step 3: verify your serialization codec — read this before upgrading Redisson
Values are opaque bytes to the server. It is your codec, not the engine, that determines whether data written before the migration is readable after it. Because Valkey stores the same bytes Redis did, an engine change alone is safe.
The danger is bundling a client upgrade into the same change. Redisson 4.1.0 removed FstCodec, FuryCodec, MarshallingCodec and SnappyCodec. If you are on an older Redisson using one of those and you upgrade as part of this project, the codec class is gone and your existing cached data becomes unreadable. It will present as a migration failure when it is actually a client upgrade failure, and you will spend a day looking in the wrong place.
Migrate the engine and upgrade the client as two separate changes, in that order. Confirm codec parity first, cut over to Valkey second, upgrade Redisson third. Our guide to choosing a Redisson codec covers the current options.
Other breaking changes worth checking if you are jumping several versions: Redisson 4.0.0 dropped the deprecated JSON config format and Spring XML configuration, renamed the RScript.ReturnType values, and moved NameMapper, NatMapper, the Geo* and the Stream* classes into new packages.
Step 4: run a validation window
Before cutting over, run both engines in parallel. Shadow reads are the cheapest useful version: serve production reads from Redis while issuing the same reads against Valkey and comparing results asynchronously. If your workload tolerates it, dual-write for a period as well. The goal is to catch a module or Lua incompatibility under real traffic rather than under synthetic tests.
Step 5: cut over, and keep a way back
Do not decommission the Redis instance at cutover. Leave it running read-only through a validation window. Because Redisson connects to both engines through the same API, rolling back means reverting a connection string and restarting — no code change, no redeployment, no dependency swap.
Step 6: verify
Compare key counts with DBSIZE and INFO KEYSPACE against your pre-migration baseline. In cluster mode, Valkey's CLUSTERSCAN iterates keys across the whole cluster, which makes a full reconciliation pass straightforward. Then compare p99 latency and error rates against baseline using Redisson client metrics and tracing. A migration is not finished when it connects; it is finished when the numbers match.
Replacing Redis Stack Modules
This is where migrations actually fail, so audit it early. Redis 8 folded the Stack modules into core. Valkey provides equivalents as separate BSD-licensed modules — valkey-json, valkey-bloom, valkey-search and valkey-ldap — which ship together in the valkey-bundle container. If you are moving to a managed service, check what it already includes before planning module deployment: Memorystore for Valkey, for instance, supports Bloom filters and JSON. Coverage is uneven either way.
| Redis capability | Valkey equivalent | Redisson object | Module needed? |
|---|---|---|---|
| RedisJSON | valkey-json — near-complete | RJsonBucket, RJsonStore | Yes |
| RediSearch | valkey-search — partial, see below | RSearch | Yes, with gaps |
| Bloom filter | valkey-bloom | RBloomFilter or RBloomFilterNative | Optional |
| RedisTimeSeries | None | RTimeSeries | No |
| Cuckoo filter | None | RCuckooFilter | Yes — no Valkey path |
| Top-K | None | RTopK | Yes — no Valkey path |
| T-Digest | None | RTDigest | Yes — no Valkey path |
| Count-Min Sketch | None | None | Rebuild client-side |
| RedisGraph | None | None | Deprecated by Redis too — migrate off regardless |
Time series: the good news
Valkey has no TS.* commands at all, which makes RedisTimeSeries the hardest blocker in most migrations. Redisson's RTimeSeries resolves it: the implementation uses no module commands, only EVAL against core data structures, so it works against any Valkey or Redis deployment. Valkey ships the complete scripting surface — EVAL, EVALSHA, the read-only variants, FCALL and the full FUNCTION and SCRIPT families — so this path is clean. The same is true of Redisson's standard RBloomFilter, which needs no module either.
Probabilistic structures: the bad news
Redisson's RCuckooFilter, RTopK and RTDigest wrap the server's CF.*, TOPK.* and TDIGEST.* commands rather than reimplementing them. Valkey provides none of those commands, so these objects cannot work against Valkey — and neither can any other client's equivalent, because the commands are simply not there. If your application uses Cuckoo filters, Top-K or T-Digest, there is currently no Valkey path for them. Find this during evaluation, not during a cutover.
Search: a genuine subset
valkey-search exposes six commands — FT.CREATE, FT.SEARCH, FT.AGGREGATE, FT.INFO, FT.DROPINDEX and FT._LIST. Absent are FT.PROFILE, FT.CURSOR, FT.ALTER, FT.EXPLAIN, index aliasing, FT.TAGVALS, autocomplete, synonyms, spellcheck and dictionaries. FT.SEARCH itself takes a reduced option set, and GEOSHAPE index fields are unsupported. Core geospatial polygon search is a separate matter — Valkey 9.0 added a BYPOLYGON option to GEOSEARCH — but that does not help an indexed GEOSHAPE query.
Concretely, three Redisson calls compile and then fail against valkey-search: profileSearch() and profileAggregate() require FT.PROFILE; readCursor() requires FT.CURSOR; and createIndex() with a GEOSHAPE field requires a type Valkey does not implement. Index creation, search, aggregation, info() and dropIndex() all work. If your search layer stays inside that core set, you are fine.
Post-Migration Hardening
Once traffic is stable, close out the operational work. Confirm TLS is enforced end to end and that you are using the valkeys:// scheme where appropriate. Re-apply ACLs and auth, including Entra ID if you use it. Review connection pool sizing against the new latency profile. If you run on Kubernetes, update readiness and liveness probes, Helm chart values and any hard-coded connection strings — see connecting Redisson to a Valkey cluster on Kubernetes.
One thing not to expect from this migration: a security improvement. Because the two projects share a codebase ancestry, they largely share a vulnerability surface. In July 2026, CVE-2026-23479 and CVE-2026-25243 were patched across both Redis 8.8 and the Valkey 9.1, 9.0 and 8.1 lines within the same window. This is a licensing and governance change, and it requires the same patching discipline afterwards as before.
Common Pitfalls
- Assuming post-fork Redis features exist in Valkey. Redis 8.8's Array type and
INCREXhave no Valkey equivalent. Check anything you adopted after Redis 7.2. - Skipping the Lua audit. Redisson's module-free objects are built on
EVAL, so on this architecture Lua compatibility is data-structure compatibility. - Upgrading the client and the engine together. See Step 3. This is the one way a "no code change" migration silently corrupts reads.
- Missing a connection string. Helm charts, Kubernetes manifests, readiness probes, CI configs and Terraform variables all hold endpoints that your application config does not.
- Trusting a typo'd URL error message. Redisson's validation error still reads "Redis url should start with redis:// or rediss://", so a malformed Valkey URL produces a message pointing you at the wrong scheme.
- Decommissioning too early. A rollback path you deleted is not a rollback path.
Frequently Asked Questions
Is Valkey compatible with Redis?
Yes. Valkey was forked from Redis OSS 7.2.4 and maintains command and wire-protocol compatibility. Existing Redis clients, commands and RESP2/RESP3 connections work unchanged. Compatibility questions arise only around features Redis added after the fork, and around Redis Stack modules.
Do I need to change my Java code to migrate from Redis to Valkey?
In most cases, no. If your client supports Valkey, the migration is an infrastructure change and your application code is untouched. With Redisson you change the connection address — the valkey:// scheme is supported directly. Code changes are only needed if you depend on Redis Stack modules.
Can I use Jedis or Lettuce with Valkey?
Generally yes, since Valkey preserves the Redis wire protocol. Note that the Valkey project's recommended Java clients are Redisson, Valkey GLIDE and valkey-java; other clients supporting Redis OSS 7.2 are compatible but are not part of the tested set. Verify cluster topology discovery against your target Valkey version before cutover.
Does Redisson support Valkey?
Yes. Redisson supports Valkey and Redis from the same client and API, including the valkey://, valkeys:// and valkey+uds:// URL schemes, Valkey Cluster mode with database selection, and Valkey Sentinel. One client library covers both engines during and after migration, so you can roll back without swapping dependencies.
Will there be downtime?
Not necessarily. Cluster migrations can run with no downtime by adding Valkey nodes as replicas, letting them replicate, then promoting them. Standalone snapshot migration requires a brief pause; live replication does not. The path you choose determines the downtime, not the engine change itself.
Can I roll back a Redis to Valkey migration?
Yes, if you plan for it. Keep the source Redis instance running read-only through a validation window rather than decommissioning it at cutover. Because Redisson connects to both engines with the same API, rollback is a connection-string revert rather than a code change or redeployment.
What happens to my Redis Stack modules?
They need replacing. Valkey provides valkey-json, valkey-bloom and valkey-search as BSD-licensed modules, though search is a subset of RediSearch. RedisTimeSeries has no Valkey equivalent, but Redisson's RTimeSeries is module-free and closes that gap. Cuckoo filters, Top-K and T-Digest have no Valkey path at all.
Next Steps
If you are still deciding between the two engines, start with our Valkey vs Redis comparison. If the decision is made, the module audit is the first thing to run and the codec check is the first thing to plan around.
Redisson gives Java teams one client and one API across both engines, along with distributed locks, client-side caching, reliable queues and integrations for Spring Cache, Spring Session, Hibernate and JCache. Compare the PRO and Community Edition feature sets, or start a free trial.