DEV Community

Libme
Libme

Posted on

Redis vs Valkey vs Dragonfly: Which In-Memory Store Should a New Project Use After the License Changes?

For most new projects, the answer is to speak the Redis protocol and keep the server swappable: Valkey is the low-risk default if you want a permissively licensed fork, Redis itself is fine if you use a managed offering or its AGPL option fits your situation, and Dragonfly is worth testing only if a single node's throughput or memory efficiency is your actual bottleneck. The license matters mostly if you redistribute the server or resell it as a service. For an app that merely connects to a cache, the client code is identical in all three cases.

This post covers what changed, how to test compatibility in an afternoon, and where each option has real limits. Details are as of late 2026; check the projects' own license files before making a legal decision.

What actually changed with Redis licensing?

In 2024, Redis moved from the BSD license to a dual source-available arrangement (RSALv2 and SSPL). That prompted the Linux Foundation to host Valkey, a fork of the last BSD-licensed Redis code (the 7.2 line), with backing from several large cloud vendors. In 2025, Redis added AGPLv3 as a licensing option for newer versions, which is OSI-approved open source again, though AGPL carries its own obligations.

What this means in practice:

  • If your app only connects to the server over the network, none of these licenses restrict you from running it internally.
  • If you ship the server inside a product you distribute, or offer it as a managed service to others, the license is a real constraint, and you should read it with a lawyer rather than a blog post.
  • If your company has a blanket "no AGPL / no SSPL" policy, that policy decides the question before technical merit does.

Takeaway: the license change is a procurement and distribution question, not a code-compatibility question for the application developer.

How do Redis, Valkey, and Dragonfly differ?

Redis Valkey Dragonfly
License (as of late 2026) Source-available options plus AGPLv3 BSD-style, Linux Foundation project Source-available (BSL-style)
Lineage Original Fork of Redis 7.2 Independent rewrite in C++
Protocol Redis (RESP) Redis (RESP) Redis (RESP), most commands
Threading model Mostly single-threaded command execution, I/O threads available Same base, with ongoing I/O threading work Multi-threaded, shared-nothing design
Module ecosystem Largest (Redis modules, vendor features) Smaller, growing Not module-compatible
Managed offerings Redis's own cloud and others Offered by major clouds as a managed option Vendor cloud, or self-host
Main drawback License complexity Feature set trails newer Redis-only additions Compatibility is "most", not "all"; younger project

I would not trust any single row without checking it yourself, particularly the managed-offering row, which changes quickly. The point of the table is the shape of the trade-off: Valkey minimizes surprise, Redis maximizes features, Dragonfly changes the performance model.

Takeaway: Valkey and Redis differ mainly in governance and newer vendor-specific features, while Dragonfly differs in architecture.

How do you test compatibility before committing?

Do not read compatibility pages; run your own command surface against each server. The usual trap is that your app uses a command, Lua script, or data type you forgot about. Here is a small script that records every command your test suite issues, then replays that set against a candidate server.

Start the candidates locally (swap the image for the one you are evaluating):

docker run -d --name cache-valkey -p 6380:6379 valkey/valkey:latest
docker run -d --name cache-redis  -p 6381:6379 redis:latest
Enter fullscreen mode Exit fullscreen mode

Then run your real integration tests against each port. For a fast sanity check of the specific features you rely on:

import redis

def check(port: int) -> dict:
    r = redis.Redis(port=port, decode_responses=True)
    results = {}

    r.flushall()
    r.set("k", "v", ex=5, nx=True)
    results["set_nx_ex"] = r.get("k") == "v"

    r.xadd("stream", {"a": "1"})
    results["streams"] = r.xlen("stream") == 1

    script = "return redis.call('INCR', KEYS[1])"
    results["lua_eval"] = r.eval(script, 1, "counter") == 1

    r.zadd("z", {"a": 1, "b": 2})
    results["sorted_set"] = r.zrange("z", 0, -1) == ["a", "b"]

    # Blocking pop with a short timeout, a common compatibility gap
    results["blpop_timeout"] = r.blpop("empty", timeout=1) is None
    return results

for name, port in [("valkey", 6380), ("redis", 6381)]:
    print(name, check(port))
Enter fullscreen mode Exit fullscreen mode

Extend it with the commands your code uses. To find those, run MONITOR against a staging instance during a test run, or grep your codebase and your libraries (queue libraries and session stores often use Lua scripts and streams you never wrote yourself).

What tripped me up in this kind of exercise: libraries that detect the server by version string. A client that checks INFO server for a specific redis_version can behave differently against a fork that reports its own version. Test with your actual client library versions, not just redis-cli.

Takeaway: compatibility is a property of your command set plus your libraries, so replay both rather than trusting a feature list.

When is Dragonfly worth the extra evaluation?

Dragonfly's pitch is that one multi-threaded process can use all cores on a large machine, where a single-threaded Redis-style process uses roughly one core for commands and you scale out with clustering. If you are running a big instance and sharding purely to get past one core, that is the situation where it deserves a benchmark. I have not run a controlled benchmark here and will not quote numbers; vendor benchmarks are measured on their chosen workloads, so run your own traffic shape.

If you are at a few thousand operations per second on a small instance, none of this matters. The cache is not your bottleneck, and the extra variable of a newer, less widely deployed server costs more in operational unknowns than it saves.

Limitations to weigh: Dragonfly does not support Redis modules, a few commands and behaviors differ, and the community and hosting options are smaller than for Redis or Valkey. If the managed service you want only offers Redis or Valkey, that constraint probably decides it. If you want the one with the strongest performance story on big single nodes and you are willing to self-host and test, Dragonfly is the one to put on your shortlist.

Takeaway: choose Dragonfly because you measured a single-node scaling problem, not because the architecture sounds modern.

What is the safest way to keep your options open?

Treat the cache as a protocol, not a product:

  1. Connect through a standard client and a single CACHE_URL environment variable (redis:// works for all three).
  2. Avoid vendor-specific modules unless the feature is worth being locked in for. If you need something like JSON documents or search inside the store, you are choosing a vendor, not a protocol.
  3. Keep Lua scripts and Streams usage in one module so a future migration has a single place to test.
  4. Run your integration suite in CI against two servers, so drift shows up in a pull request instead of a migration weekend.
# docker-compose.ci.yml
services:
  cache-a:
    image: valkey/valkey:latest
  cache-b:
    image: redis:latest
Enter fullscreen mode Exit fullscreen mode

If you want the managed version of the open-source fork without running servers yourself, check whether your existing cloud provider's managed Valkey offering covers your region and version needs before looking elsewhere. If you want Redis's own feature set and support, Redis Cloud is the managed route from the vendor itself, with the usual limitation that you are tied to its roadmap and pricing model.

Takeaway: a CACHE_URL variable and a two-server CI matrix make this decision reversible.

FAQ

Is Valkey a drop-in replacement for Redis?
For Redis 7.2-era features, largely yes: the same protocol, commands, and clients work. Features that Redis added after the fork, or Redis-specific modules, may be missing, so replay your own command set before switching.

Can I still use Redis for free after the license change?
Yes for running it internally as a cache or queue backend. The license restrictions bite mainly if you redistribute the server or offer it as a service, and the AGPL option adds its own source-sharing obligations.

Is Dragonfly faster than Redis?
On large multi-core machines it can be, because it uses multiple threads for command execution, but the gain depends entirely on your workload. Benchmark your own traffic before deciding.

Bottom line

Default to Valkey or managed Redis, whichever your cloud and legal team already accept, and write your application against the protocol so you can change your mind. Pick Redis when you need its newer or module-based features. Evaluate Dragonfly only when you have a measured single-node throughput or memory problem and can accept self-hosting and a smaller ecosystem. Everyone else should spend the afternoon on a two-server CI matrix, not on picking a winner.

Related reading

Top comments (0)