Okay, so I held off on writing this for almost a year because I assumed the dust would settle. It mostly hasn’t. Valkey shipped, AWS shipped it, every major Linux distro now packages it as the default key-value store, and people keep asking me the same question on Twitter: did you actually switch?
Short answer: half of my production caches now run Valkey, half still run Redis. The cutover wasn’t a manifesto. It was three pull requests, a few Terraform diffs, and two weekends of checking that nothing broke. Nothing broke.
This post is the boring version of what happened. Not the license drama, not the Reddit threads, just the parts that actually affect what you deploy. I’ll tell you which workloads I moved, which I kept on Redis, and why the choice isn’t as obvious as either side claims.
What’s actually different between Valkey and Redis
I had to keep reminding myself of this: Valkey forked from Redis 7.2.4 in March 2024 after Redis Inc. moved away from BSD-3 to a dual SSPL/RSALv2 license. The Linux Foundation picked up the fork, several of the most active core contributors went with it (including Madelyn Olson at AWS), and AWS, Google Cloud, Oracle, and a stack of others put real engineers on it.
In practice that means the wire protocol is identical. RESP2, RESP3, cluster mode, sentinel. All of it. My existing redis-cli works against a Valkey 8 instance and so does the ioredis client I had on a Node.js API I haven’t touched in two years. I didn’t change a single line of application code on the services I moved.
The differences are in licensing, governance, and now in roadmap. Valkey 8 added multi-threaded I/O improvements that Redis Inc. is also working on but shipped later. Redis 8.x has Vector Sets and a different vector-similarity story. Both are real. Neither is decisive for most workloads.
# Same client, same protocol, both servers respond
$ redis-cli -h cache.prod.internal -p 6379 PING
PONG
$ redis-cli -h cache-vk.prod.internal -p 6379 PING
PONG
If you’re using Redis as a cache or a queue with BullMQ or Sidekiq, the move is genuinely uneventful.
Where I switched: caching layer for a Next.js app
The biggest case was a Next.js app I run that uses Redis for session storage and for caching API responses from a vendor. Hot path traffic, maybe 4k req/s at peak, mostly GET / SET / EXPIRE.
I migrated this in February. The actual steps were:
- Spun up a Valkey 8 cluster on AWS ElastiCache, which shipped Valkey support at about a third lower list price than the equivalent Redis offering.
- Used Redis’s
MIGRATEcommand to copy a few keys for sanity. For the live cutover I dual-wrote for 48 hours and then switched the read endpoint. - Deleted the old cluster.
Total downtime: zero. Total code change: one environment variable. The cost change was real and not marketing fluff. For this workload, my monthly bill dropped from about $214 to $145.
The interesting part wasn’t the savings. It was that nothing in our error budgets, latency graphs, or p99s moved. I keep a private dashboard for this kind of decision and the only delta was the line item on the AWS invoice.
Where I stayed on Redis: the Stack features
The other half of my stack uses Redis Stack. Specifically RediSearch and RedisJSON. I have one service that does full-text and vector search over a few hundred thousand documents, and another that stores nested JSON state for a workflow engine.
Valkey 8 didn’t ship equivalents. There are forks like valkey-search and valkey-json but they aren’t at the same maturity level. The Redis Stack modules are battle-tested, the docs are good, and the licensing change doesn’t actually bite me if I’m just running them in EC2. The RSALv2/SSPL terms restrict cloud providers who want to resell Redis as a service, not most end-user companies running it as part of their own product.
So I kept Redis Stack on the two services that needed it. Plain key-value caches and queues are on Valkey.
# docker-compose snippet, Valkey for cache, Redis Stack for search
services:
cache:
image: valkey/valkey:8.1-alpine
ports: ["6379:6379"]
command: valkey-server --save "" --appendonly no
search:
image: redis/redis-stack-server:7.4.0-v0
ports: ["6380:6379"]
The point is you can mix them. They speak the same protocol on the same network, and your application code doesn’t care.
The performance question, with actual numbers
I keep seeing benchmark posts comparing Valkey 8 and Redis 7.4 that have Valkey winning by 2 to 3x on ops/sec. They’re real but the conditions matter. Valkey 8’s multi-threaded I/O is a meaningful upgrade for high-connection workloads. If you have one Node.js process pulling 5k req/s against a single Redis instance, you’ll see modest gains. If you have 200 connections from different services hammering the same instance, you’ll see big gains.
I ran a sloppy benchmark on my own gear before I committed:
# Single client, 50 parallel connections, GET-heavy
$ redis-benchmark -h cache-redis -t get -n 1000000 -c 50 -q
GET: 138217.51 requests per second
$ redis-benchmark -h cache-valkey -t get -n 1000000 -c 50 -q
GET: 161031.69 requests per second
That’s about 16% faster, not 200%. The benchmarks claiming massive gains usually run with hundreds of clients, which is where the I/O threading pays off. Your workload probably looks more like mine than like the benchmark.
The Valkey performance writeup is honest about this. Read it before you make claims in your stand-up.
The boring operational stuff that actually matters
Three things I cared about more than the license fight.
Client library support. All the major clients (node-redis, ioredis, redis-py, go-redis, jedis, lettuce) explicitly support Valkey because the protocol is the same. The official Valkey project is also building valkey-glide, a multi-language client co-developed by AWS. It’s good. I haven’t switched off ioredis because it works, but glide is a real option now.
Observability. Same INFO, same MONITOR, same SLOWLOG. My Datadog dashboards didn’t need a single change. Prometheus exporters for both are interchangeable in my setup.
Hosted options. AWS ElastiCache for Valkey is GA and cheaper. Google Cloud has Memorystore for Valkey. Aiven has both. DigitalOcean Managed Databases offers both. If you’re self-hosting, the Docker images are equivalent in resource footprint.
The thing nobody tells you: ElastiCache for Redis 7.x and ElastiCache for Valkey 8.x are not the same SKU. You can’t just “upgrade.” You spin up a new cluster and migrate. That’s how I did it and it’s the only sane way.
So what do I actually recommend
If you’re using Redis as a cache or a queue and you don’t depend on Stack modules, go to Valkey. It’s cheaper on managed services, the performance is at least equivalent, the licensing is fully open source under BSD-3, and the migration is genuinely trivial.
If you depend on RediSearch, RedisJSON, RedisTimeSeries, or RedisBloom in production today, stay on Redis. The Valkey ecosystem will eventually fill those gaps, but I don’t bet production on “eventually.”
If you’re greenfield and you need search or vector capabilities, evaluate both Redis Stack and a separate purpose-built tool. Postgres can handle a lot more than people give it credit for, and I made that case in detail in my post on Postgres JSONB.
The honest answer to “should I switch” is: pick the boring choice. For caches and queues, Valkey is the boring choice now. For everything else, you already know.
If you want a sanity check on a specific workload, I take consulting calls on this kind of infrastructure decision. There are details on my portfolio.