Redis vs Valkey

RedisValkeyDatabases

You need a fast in-memory store. Maybe it's for caching, rate limiting, session management, or a pub/sub layer. You start looking at Redis, because that's what everyone uses. Then you notice something odd: AWS ElastiCache defaults to Valkey now. Google Cloud Memorystore supports Valkey. The Linux Foundation is backing it. Half the ecosystem seems to have quietly moved to something you hadn't heard of six months ago.

Here's what happened. In March 2024, Redis Labs changed the Redis license from BSD 3-Clause to SSPL + RSALv2, neither of which qualifies as open source. Within weeks, the Linux Foundation announced Valkey, a community fork of Redis 7.2.4 that keeps the original BSD license. AWS, Google Cloud, Oracle, and others backed it immediately. Not a protest fork. A "we need this to stay open and we'll fund the engineering" fork.

So now you have two options where there used to be one, and they're wire-protocol compatible. Same redis:// URLs, same client libraries, same commands. The difference is licensing and governance. Here's what that means for your project.

Contents

Quick Comparison

RedisValkey
LicenseSSPL + RSALv2 (not OSI-approved)BSD 3-Clause (fully open source)
GovernanceRedis Ltd. (single company)Linux Foundation (community-governed)
ProtocolRESP (Redis Serialization Protocol)RESP (same protocol, full compatibility)
Client librariesAll Redis clientsSame Redis clients, no changes needed
PerformanceSub-millisecondSub-millisecond (same codebase origin)
Data structuresStrings, lists, sets, sorted sets, hashes, streams, etc.All of the above, same set
ClusteringRedis ClusterRedis Cluster compatible
Managed offeringsRedis Cloud, AWS ElastiCache (Redis), Azure CacheAWS ElastiCache (Valkey), Layerbase Cloud, others

The protocol compatibility is the important row. Valkey speaks the exact same RESP protocol as Redis, so every client library, CLI tool, and existing codebase works with both. Byte-level compatibility, not an approximation.

Run Both Locally with SpinDB

The fastest way to try both is SpinDB. One CLI, both engines, no Docker. (What is SpinDB?)

Install SpinDB:

bash
npm i -g spindb    # npm
pnpm add -g spindb # pnpm

Now create one instance of each:

bash
spindb create myredis -e redis --start
spindb create myvalkey -e valkey --start

SpinDB assigns different ports automatically so both run simultaneously. Check the URLs:

bash
spindb url myredis
spindb url myvalkey
text
redis://127.0.0.1:6379
redis://127.0.0.1:6380

Both URLs use the redis:// scheme. Not a bug. Valkey uses the same protocol, so the same URI format applies.

Same Code, Both Engines

This is what surprises people coming from other database forks. Normally a fork means a new driver, new connection logic, sometimes a new query dialect. With Valkey, you change one string (the URL) and everything else is identical.

Set Up the Project

bash
mkdir redis-vs-valkey && cd redis-vs-valkey
pnpm init
pnpm add redis
pnpm add -D tsx typescript

Yes, you install the redis npm package to talk to Valkey. No separate Valkey client exists. The standard node-redis package works with both because the protocol is identical.

Create a file called compare.ts:

typescript
import { createClient } from 'redis'

const REDIS_URL = 'redis://localhost:6379'
const VALKEY_URL = 'redis://localhost:6380'

async function runDemo(name: string, url: string) {
  const client = createClient({ url })
  await client.connect()
  console.log(`\nConnected to ${name} at ${url}`)

  // Basic SET/GET
  await client.set(`${name}:greeting`, `Hello from ${name}`)
  const greeting = await client.get(`${name}:greeting`)
  console.log(`  GET: ${greeting}`)

  // Atomic counter
  const counterKey = `${name}:hits`
  await client.set(counterKey, '0')
  await client.incr(counterKey)
  await client.incr(counterKey)
  await client.incrBy(counterKey, 8)
  const count = await client.get(counterKey)
  console.log(`  Counter: ${count}`)

  // Hash (like a session or user object)
  const hashKey = `${name}:user:1`
  await client.hSet(hashKey, {
    name: 'Alice',
    email: 'alice@example.com',
    role: 'admin',
  })
  const user = await client.hGetAll(hashKey)
  console.log(`  Hash: ${JSON.stringify(user)}`)

  // Sorted set (leaderboard-style)
  const leaderboard = `${name}:scores`
  await client.del(leaderboard)
  await client.zAdd(leaderboard, [
    { score: 100, value: 'alice' },
    { score: 250, value: 'bob' },
    { score: 175, value: 'charlie' },
  ])
  const top = await client.zRangeWithScores(leaderboard, 0, 2, { REV: true })
  console.log(`  Sorted set (top 3):`)
  for (const entry of top) {
    console.log(`    ${entry.value}: ${entry.score}`)
  }

  // TTL-based expiration
  await client.set(`${name}:temp`, 'expires soon', { EX: 60 })
  const ttl = await client.ttl(`${name}:temp`)
  console.log(`  TTL: ${ttl} seconds`)

  // Clean up
  await client.del([
    `${name}:greeting`,
    counterKey,
    hashKey,
    leaderboard,
    `${name}:temp`,
  ])
  await client.close()
  console.log(`  Disconnected from ${name}`)
}

// Run the same operations against both
await runDemo('Redis', REDIS_URL)
await runDemo('Valkey', VALKEY_URL)

console.log('\nSame code. Same package. Same results.')

Run it:

bash
npx tsx compare.ts
text
Connected to Redis at redis://localhost:6379
  GET: Hello from Redis
  Counter: 10
  Hash: {"name":"Alice","email":"alice@example.com","role":"admin"}
  Sorted set (top 3):
    bob: 250
    charlie: 175
    alice: 100
  TTL: 60 seconds
  Disconnected from Redis

Connected to Valkey at redis://localhost:6380
  GET: Hello from Valkey
  Counter: 10
  Hash: {"name":"Alice","email":"alice@example.com","role":"admin"}
  Sorted set (top 3):
    bob: 250
    charlie: 175
    alice: 100
  TTL: 60 seconds
  Disconnected from Valkey

Same code. Same package. Same results.

Every operation produces identical results. SET, GET, INCR, HSET, ZADD, EXPIRE: all the same. The only difference in the entire file is the URL string.

What Actually Differs

If the code and protocol are the same, why does the fork matter? Three reasons.

1. Licensing

This is the big one. Redis is now dual-licensed under SSPL and RSALv2:

  • SSPL requires that if you offer Redis as a service, you must open-source your entire service stack. AWS, Google Cloud, and others can't (or won't) comply.
  • RSALv2 allows use in applications but prohibits using Redis to build a competing database product or service.

Neither license is approved by the Open Source Initiative. If your company requires OSI-approved licenses, Redis no longer qualifies.

Valkey is BSD 3-Clause. Use it for anything, including building a managed database service on top of it. No restrictions, no ambiguity.

For most developers building products (not database services), the practical impact of the Redis license change is minimal. You can still embed Redis in your app. But if you value the open-source ecosystem or want to avoid licensing complications down the road, Valkey removes that concern entirely.

2. Feature Divergence

As of early 2026, Valkey and Redis have started to go their own ways:

  • Valkey 8 introduced multi-threaded I/O that can significantly improve throughput on multi-core machines. Redis has its own threading work in progress, but the implementations differ.
  • Redis continues to develop Redis Stack modules (RedisJSON, RediSearch, RedisGraph). Some of these are available under more permissive licenses, but the packaging is Redis-specific.
  • Valkey is working on its own extension system that will allow community-built modules without the same licensing constraints.

Today, for core data structure operations (strings, lists, sets, sorted sets, hashes, streams, pub/sub), they're functionally identical. The divergence is at the edges: modules, extensions, and performance optimizations.

3. Governance

Redis is controlled by Redis Ltd. They decide the roadmap, the license, and what gets merged. Not inherently bad, but the 2024 license change proved that a single-company project can change its terms whenever it wants.

Valkey is a Linux Foundation project with a steering committee drawn from multiple organizations. Changes to governance or licensing require community consensus. If long-term stability matters to you, that's a stronger guarantee than one company's good intentions.

When to Pick Redis

Pick Redis when:

  • You're an existing Redis Enterprise customer. If you're paying for Redis Cloud and using Redis Stack modules (RedisJSON, RediSearch, RedisTimeSeries), switching has a real cost. The integrated experience is hard to replicate elsewhere.
  • You depend on Redis Stack modules. Some don't have Valkey equivalents yet. If your app relies heavily on RediSearch, staying on Redis makes sense until Valkey's extension ecosystem catches up.
  • Your organization is fine with SSPL/RSALv2. If your legal team has no issue with the licenses and you're not building a competing database service, the license change may not affect you at all.

When to Pick Valkey

Pick Valkey when:

  • You're starting a new project. No existing Redis infrastructure? No reason to start with the more restrictive license. Valkey gives you the same capabilities with BSD 3-Clause.
  • OSI compliance is required. Government agencies, open-source projects, or companies that mandate OSI-approved licenses. Valkey is the only option.
  • You're building infrastructure or platforms. If your platform includes an in-memory store as a component, Valkey's BSD license means no worrying about SSPL's service-offering restrictions.
  • You want to avoid license risk. The license changed once. It can change again. Community governance makes sudden shifts much less likely.

I'll be direct: for new projects, Valkey is the safer choice. Same technology, same performance, same client ecosystem, with an unambiguous open-source license. The only reason to pick Redis for a new project is if you specifically need a Redis Stack module that Valkey doesn't support yet.

Running Valkey on Layerbase Cloud

Want a managed Redis-compatible instance instead? Layerbase Cloud offers Valkey. Grab the language-specific Quick Connect snippet from the dashboard and use that directly for TLS clients.

Wrapping Up

The Redis-to-Valkey story is simple. Redis changed its license. The community forked it. The fork is protocol-compatible, so switching requires zero code changes. The deciding factor is licensing and governance, not technology.

Manage your local instances:

bash
spindb stop myredis     # Stop Redis
spindb stop myvalkey    # Stop Valkey
spindb start myredis    # Start Redis again
spindb start myvalkey   # Start Valkey again
spindb list             # See all your instances

SpinDB supports 20+ engines, so you can run Redis, Valkey, PostgreSQL, MongoDB, and whatever else you need from one CLI. Layerbase Desktop provides a macOS GUI if you'd rather skip the terminal.

Something not working?