Milind Daraniya

Valkey 9.1: What Developers Should Know About the Redis-Compatible Alternative in 2026

Published September 26th, 2026 26 min read

Redis has been used in many applications for years.

I have used Redis-style systems for things like:

Cache
Queue
Session
Rate limiting
Temporary data
Pub/Sub
Locks
Application state

But in 2026, there is another name that backend developers need to know:

Valkey.

Valkey is an open-source continuation of the Redis OSS codebase and is maintained under the Linux Foundation. Its current 9.1 release line adds improvements across security, observability, performance, efficiency and tooling.

As of September 2026, Valkey 9.1.2 is the latest stable 9.1 patch release, released on September 1, 2026.

This makes Valkey worth looking at for developers who are deciding what to use for caching and high-speed application data.

Why are developers talking about Valkey?

The biggest reason is not that developers suddenly need another cache.

The bigger reason is the direction of the project.

Valkey is an open-source, vendor-neutral project, and it continues developing its own features instead of remaining only a copy of an older Redis release.

So the architecture looks more like:

Redis OSS
    ↓
Valkey fork
    ↓
Valkey-specific development
    ↓
New security
New performance
New observability
New features

This is why Valkey 9.1 is more interesting than simply saying:

"Valkey is another Redis."

It is compatible with important Redis concepts, but it is becoming its own project.

Is Valkey compatible with Redis?

This is where developers need to be careful.

Valkey's official migration documentation says it is compatible with Redis OSS 7.2 and earlier.

It supports the Redis Serialization Protocol, or RESP, including RESP2 and RESP3, and existing Redis client libraries can connect to Valkey without code changes in compatible scenarios.

That means an application using a normal Redis client can often connect to Valkey with very little application-level change.

For example, an application may still have configuration conceptually like:

Host
Port
Username
Password
Database

and the client communicates using the same basic protocol.

But I would never assume:

Redis version X
      ↓
Valkey

will always be a completely transparent replacement.

Version and feature compatibility need to be checked.

The important Redis compatibility limitation

This is probably the most important point in this article.

Valkey's migration documentation says Redis OSS 7.2 and earlier are compatible, but Redis Community Edition 7.4 and later produce data files that are not compatible with Valkey.

So the statement:

"Valkey is fully compatible with all Redis versions."

would be wrong.

The safer way to think about it is:

Redis OSS 7.2 and earlier
        ↓
Strong compatibility path

Newer Redis Community Edition
        ↓
Check compatibility and migration method

This matters when planning a migration.

You should identify the exact Redis product and version first.

Valkey 9.1 adds database-level ACLs

One of the features I find particularly useful in Valkey 9.1 is database-level access control.

Previously, ACL rules could restrict commands and keys, but the permissions applied across databases.

Valkey 9.1 adds the ability to restrict a user to specific databases.

For example:

Application User
      ↓
Database 0
Database 1

while:

Database 2

can be denied.

The Valkey documentation gives an example like:

ACL SETUSER app-user on >secretpass +@all ~* db=0,1

Then selecting database 2 returns a permission error.

For multi-tenant or shared infrastructure, this can be useful.

Why this matters for SaaS

Imagine a shared Valkey instance:

Tenant A
Tenant B
Tenant C
Tenant D

Application access should not simply mean:

"User has a password, therefore user can access everything."

Access control should be part of the architecture.

Database-level ACLs give another control boundary.

This does not replace proper key-prefix design or application authorization.

But it adds another layer.

I would think about security as:

Application authorization
        +
Valkey ACL
        +
Network security
        +
Secret management

rather than expecting one feature to solve everything.

Lua is now separated into a module

Valkey 9.1 also moves its Lua scripting engine into a separate module.

This reduces the scripting functionality inside the core server and allows operators to disable Lua completely when it is not required. Valkey also added a new Scripting Engines section to the INFO command.

This is interesting from a security perspective.

If an application does not need server-side scripting, reducing unnecessary functionality can reduce the attack surface.

This is the type of change that may not affect normal application code at all.

But it matters for infrastructure management.

TLS handling is improved

Valkey 9.1 also improves TLS management.

The server can expose TLS certificate expiration dates through INFO, which can help identify certificates that are about to expire.

It also supports automatic background TLS certificate reloading and certificate authentication using Subject Alternate Name URI values for mTLS scenarios.

This is particularly useful for production environments.

Certificate expiry is one of those problems that is easy to ignore until suddenly:

Application
    ↓
TLS connection
    ↓
Certificate expired
    ↓
Connection failure

A monitoring-friendly system should make these problems visible before they cause an outage.

JSON logging

Valkey 9.1 can emit logs in JSON format using:

log-format json

This means logs can be consumed more directly by observability platforms without custom text parsing.

For example, a log pipeline can become:

Valkey
  ↓
JSON logs
  ↓
Log collector
  ↓
Search / alerts / dashboards

instead of:

Valkey
  ↓
Text logs
  ↓
Regex parsing
  ↓
Structured data

This is a small configuration feature but useful in production systems.

New thread usage metrics

Valkey 9.1 also adds metrics for main-thread and I/O-thread usage.

This is important because CPU percentage by itself can sometimes be misleading for Valkey workloads. The project explains that threads can appear close to 100% CPU because of busy loops even when actual work is relatively low.

The new cumulative usage metrics give operators better visibility into the actual work being done by the threads.

For me, this is a good example of observability becoming part of database design.

It is not enough to know:

CPU = 80%

We also want to know:

How much work is the main thread doing?
How much work are I/O threads doing?
Where is the bottleneck?

Valkey 9.1 improves I/O threading

Valkey 9.1 redesigns its I/O threading communication model.

The Valkey team reports throughput improvements of up to 17% across a range of workloads from this change.

Again, I would not translate that into:

"Every application becomes 17% faster."

Benchmarks are workload-dependent.

But the direction is important.

Valkey is continuing to improve how it uses multiple I/O threads instead of relying only on the traditional execution model.

The single-server performance number is interesting

Valkey reports 2.1 million requests per second for a specific single-server benchmark using:

512-byte payloads
9 I/O threads
Pipeline depth 10

This is a benchmark configuration, not a general application guarantee.

I always prefer reading benchmark conditions.

For a real application, performance depends on:

Command type
Payload size
Network
Pipelining
Connections
CPU
Memory
Workload distribution
Persistence
Replication

So don't take one benchmark number and apply it directly to your application.

Streams are faster

Valkey 9.1 also improves stream range operations.

The project reports that:

XRANGE
XREVRANGE

can be up to 30% faster due to hot-path optimizations.

This matters for applications that use streams for:

Events
Queues
Activity data
Real-time processing
Event-driven workflows

For applications that do not use streams, this change may have almost no practical impact.

That is why I prefer mapping release notes to the actual workload.

GET performance is also improved

Valkey 9.1 changes the string embedding threshold and reports up to 30% higher throughput for string GET operations in relevant workloads.

This is especially interesting for cache-heavy applications.

For example:

User session
    ↓
GET key
    ↓
Return cached data

When an application performs huge numbers of small GET operations, low-level efficiency can matter.

Again, the actual benefit depends on the workload.

Sorted sets get improvements

Sorted sets are often used for:

Leaderboards
Ranking
Scheduled work
Priority data
Time-based processing

Valkey 9.1 improves skiplist query processing for sorted sets.

Commands such as:

ZRANGEBYSCORE
ZRANGEBYLEX

can benefit from these optimizations.

This is useful because sorted sets are one of those data structures that can quietly become performance-critical in large systems.

Memory usage is one of the biggest improvements

Performance is not the only thing that matters.

Memory is extremely important for an in-memory datastore.

Valkey 9.1 introduces internal optimizations that reduce memory overhead for strings and sorted sets. The project reports up to 20% memory reduction for strings under 128 bytes and up to 10% lower memory use for sorted sets under the described workloads.

A separate Valkey technical deep dive explains that these changes reduce per-key overhead and can become significant when an instance contains millions of keys.

For example:

1 million keys

and:

10 million keys

can make small per-key savings much more important.

This is one reason I pay attention to memory efficiency in caching systems.

Why small keys matter

Suppose an application has millions of keys like:

user:1
user:2
user:3
...

Even if every value is small, the database still has internal metadata and object overhead.

Saving a small amount per key can add up.

That is why database-level memory optimization can be more important than it initially sounds.

Rehashing is improved

Valkey 9.1 also improves hash table rehashing.

Rehashing happens as the number of keys changes.

Poorly handled rehashing can introduce latency spikes.

Valkey 9.1 changes some internal behaviour to reduce the impact during keyspace growth and bulk deletions.

For a large production instance, predictable latency is often more important than a benchmark that only measures average throughput.

I care about:

Average latency
p95 latency
p99 latency
Latency spikes

not just:

Requests per second

Faster bulk delete operations

Valkey 9.1 also improves bulk deletion behaviour for commands such as:

SREM
ZREM
HDEL

The server can pause certain internal hash-table resizing work during the operation to avoid unnecessary rehashing.

This can matter in systems where large amounts of temporary data are removed regularly.

For example:

Expired campaign
        ↓
Remove many keys
        ↓
Cleanup workload

A better deletion path can reduce unnecessary overhead.

Replicas also become more efficient

Valkey 9.1 changes replica creation when AOF is enabled.

The replica can reuse the received RDB file instead of generating a new snapshot for the initial AOF base file.

This is more of an infrastructure optimisation.

Most application developers will never touch this directly.

But for teams operating large Valkey clusters, replication efficiency affects:

Failover
Recovery
Scaling
Replica creation
Deployment
Operational cost

This is where datastore engineering becomes more than just application caching.

Valkey is useful for more than caching

Sometimes we still think of Redis-like systems only as:

Cache

But Valkey supports a much wider range of workloads.

For example:

Cache
Queues
Pub/Sub
Streams
Sessions
Rate limiting
Locks
Leaderboards
Temporary state
Primary data

Valkey itself describes its use cases as including caching, message queues and primary-database workloads.

That doesn't mean I would replace MySQL or PostgreSQL with Valkey for every application.

The right datastore depends on the type of data.

But Valkey can be much more than a simple cache layer.

Laravel applications can use Valkey

For Laravel developers, the interesting point is that the application architecture does not have to change completely.

Laravel applications commonly use Redis-compatible infrastructure for:

Cache
Queue
Session
Rate limiting

Because Valkey speaks the RESP protocol and is compatible with Redis OSS 7.2 and earlier client behaviour, many Redis clients can communicate with it.

The important word here is:

test.

Don't change production from Redis to Valkey only because the configuration looks similar.

Check the actual framework version, client library and features being used.

Node.js applications can also use it

The same architecture applies to Node.js.

For example:

Node.js API
      ↓
Valkey
      ↓
Cache

The application still needs a client library that supports the protocol and features being used.

Again, compatibility should be tested against the exact client and exact server version.

The advantage is that application code can often remain relatively stable when the datastore protocol and basic commands remain compatible.

Docker makes testing easier

One practical way to evaluate Valkey is Docker.

The official Valkey release page provides Docker images such as:

valkey/valkey:9.1.2
valkey/valkey:9.1.2-trixie
valkey/valkey:9.1.2-alpine
valkey/valkey:9.1.2-alpine3.24

for the current 9.1.2 release.

For local testing:

docker run --rm -p 6379:6379 valkey/valkey:9.1.2

Then connect using your normal Redis-compatible client.

This is a simple way to test application compatibility without changing the production server.

Don't start by migrating production

I would first create a test environment:

Application
      ↓
Valkey 9.1.2
      ↓
Run existing test suite

Then test:

Cache
Queue
Session
Locks
Pub/Sub
Streams
Rate limiting

Then compare:

Memory
Latency
CPU
Throughput
Error rate

Only after that would I consider production migration.

Existing Redis data needs planning

Valkey's migration documentation provides several approaches for compatible Redis OSS versions.

These include:

Physical migration
Replication
Specific-key migration

For a compatible Redis OSS 7.2-or-earlier source, Valkey can read compatible RDB/AOF data, and existing Redis client libraries can connect using RESP.

For a large production system, replication-based migration can be useful because it allows the new Valkey instance to synchronize before switching application traffic.

But the exact migration plan depends on:

Redis version
Data size
Write volume
Persistence mode
Cluster setup
Downtime requirement
Application traffic

There is no single migration method that is correct for every system.

Cluster migration also needs planning

For Redis Cluster to Valkey Cluster migrations, the official documentation describes adding Valkey nodes as replicas, allowing them to synchronize, promoting them and then removing the old Redis nodes.

That is a different process from simply stopping one server and copying files.

For a large cluster, I would never treat migration like a simple package replacement.

It is an infrastructure project.

What about security?

Valkey 9.1 includes several security-related improvements:

Database-level ACLs
Lua isolation
TLS certificate visibility
TLS certificate reloading
mTLS-related certificate support

These features can make production operation easier to control.

But the application still needs proper security.

For example:

Don't expose port 6379 publicly
Use authentication
Use TLS where required
Restrict network access
Rotate secrets
Apply least privilege
Monitor failed connections

A secure datastore configuration should be part of the deployment design.

What I would monitor

For a production Valkey server, I would monitor:

Memory usage
Connected clients
Commands/sec
Latency
Evicted keys
Expired keys
Hit ratio
Replication status
CPU
I/O thread usage
Persistence
Failed connections

The new observability features in 9.1 make some of this easier to understand.

I would also monitor application metrics.

For example:

Cache hit rate
Cache miss rate
Queue delay
API latency
Database latency

A Valkey server can look healthy while the application itself is performing badly because of poor cache usage.

Don't cache everything

Having a fast datastore does not mean every database query should be cached.

For example:

GET user
    ↓
Cache

may make sense.

But caching a huge report that is requested once every three days may not.

The important question is:

Does caching reduce expensive work enough
to justify its memory and invalidation cost?

Cache invalidation is still a real engineering problem.

Valkey cannot decide that for us.

Cache invalidation remains important

Suppose we cache:

product:100

Then the product changes.

Now:

MySQL
   ↓
New price = ₹500

Valkey
   ↓
Old price = ₹450

The cache is fast.

The cache is also wrong.

So we need a strategy:

TTL
Invalidation
Versioned keys
Write-through
Cache-aside

A faster cache with incorrect data is still a problem.

Valkey 9.1 and high-scale SaaS

For a large SaaS application, I think Valkey becomes particularly interesting when it is used for workload separation.

For example:

MySQL / PostgreSQL
        ↓
Permanent business data

Valkey
        ↓
Fast temporary state

Queue
        ↓
Background jobs

Stream
        ↓
Event processing

This gives each system a clearer responsibility.

Instead of asking one database to do everything, we can choose the right storage layer for each workload.

Valkey 9.2 is already being prepared

As of September 19, 2026, Valkey 9.2.0-rc1 has already been released for testing. It was published on September 16, 2026.

That means developers looking at the ecosystem today should distinguish between:

Valkey 9.1.x
Stable release line

and:

Valkey 9.2
Release candidate

For production, I would stay with the current stable release unless there is a specific reason to test the release candidate.

For development and compatibility testing, testing 9.2 can be useful.

Why I would test 9.1.2 now

If I am evaluating Valkey today, I would use:

Valkey 9.1.2

rather than the original 9.1.0 release.

The 9.1.2 release includes security fixes, including fixes related to RDMA connection handling and the Lua script debugger use-after-free issue.

So when evaluating a stable release line, I prefer the latest patch release in that line.

My basic Valkey evaluation process

For an existing application, I would do:

Identify current Redis version
        ↓
Check Redis product
        ↓
Check client library
        ↓
Check used commands/features
        ↓
Start Valkey 9.1.2
        ↓
Run application tests
        ↓
Test cache
        ↓
Test queue
        ↓
Test sessions
        ↓
Test streams / Pub/Sub
        ↓
Measure memory and latency
        ↓
Test migration
        ↓
Test rollback
        ↓
Evaluate production

This gives much better confidence than simply changing:

REDIS_HOST

and hoping everything works.

Final thoughts

Valkey 9.1 is interesting because it is no longer only a discussion about a Redis-compatible server.

It is becoming a rapidly developing datastore with its own improvements.

The 9.1 release adds:

Database-level ACLs
Better TLS handling
JSON logging
Thread-level observability
Improved I/O threading
Faster streams
Faster GET workloads
Sorted-set optimizations
Lower memory overhead
Better rehashing
Better replica creation
CLI improvements

The Valkey project reports substantial improvements in several benchmark areas, but actual application results will depend on the workload.

The compatibility story is also important.

Valkey is designed as a continuation of Redis OSS and supports the RESP protocol, but the exact migration path depends on the Redis version. Official documentation specifically identifies Redis OSS 7.2 and earlier as the compatible migration path and warns that Redis Community Edition 7.4+ data files are not directly compatible.

For me, the right way to think about Valkey is:

Not simply:

"Redis replacement"

But:

"An open-source high-performance datastore
with strong Redis OSS compatibility
and its own development direction."

For a new caching or real-time backend project, Valkey 9.1 is worth evaluating.

For an existing Redis application, I would not migrate only because the name is popular.

I would first check:

Version compatibility
Client compatibility
Data migration
Commands
Modules
Performance
Memory
Security
Operations

Then test the real application.

The most important lesson is the same as with any infrastructure change:

Compatible
        ≠
Identical

A good migration starts by understanding exactly what the current application is using and then testing the new system against those real requirements.