Skip to content

Redis vs Valkey

8 min readRedisValkeyDatabases

Short version: both are fine, both speak the same protocol, and the license argument that created the fork is mostly over. Redis 8 has been available under the OSI-approved AGPLv3 since May 2025. If you were holding out for Valkey purely because Redis was not open source, that reason is gone. What is left is governance, the AGPL's network-use clause, and which feature set you want.

Here is how it got complicated. In March 2024, Redis Ltd. 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. AWS ElastiCache defaults to Valkey to this day.

Then Redis reversed course. On 1 May 2025, Redis announced that Redis 8 adds AGPLv3 as an additional licensing option alongside RSALv2 and SSPLv1, and folded the old Redis Stack modules (JSON, Time Series, probabilistic types, the query engine) into core under that license. AGPLv3 is OSI-approved, so Redis 8 and later is open source again by the definition that started the fight.

So you have two options where there used to be one, they're wire-protocol compatible, and the deciding factors are narrower than they were two years ago. Same redis:// URLs, same client libraries, same commands. Here's what actually differs now.

Contents

Quick Comparison

RedisValkey
LicenseAGPLv3, RSALv2 or SSPLv1 since Redis 8 (AGPLv3 is OSI-approved)BSD 3-Clause (permissive, no copyleft)
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, plus JSON, time series and vector sets in core since Redis 8The same core set; JSON and search live in separate Valkey modules
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 the Layerbase CLI

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

Install the CLI:

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

Now create one instance of each:

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

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

bash
lbase url myredis
lbase 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 used to be the whole argument. It is now a narrower one. Since Redis 8, you pick one of three licenses:

  • AGPLv3 is OSI-approved, so an "OSI-approved only" policy is satisfied. The catch is the network-use clause: if you modify Redis itself and expose it over a network, you owe those modifications back. Using unmodified Redis behind your app does not trigger it, but plenty of legal teams block AGPL outright rather than reason about the boundary.
  • SSPL requires that if you offer Redis as a service, you 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.

Versions before Redis 8 do not have the AGPL option, so an older pinned Redis is still SSPL/RSALv2 only.

Valkey is BSD 3-Clause. Use it for anything, including building a managed database service on top of it, with no copyleft obligation and nothing to reason about. That is a weaker advantage than it was in 2024, but it is still the more permissive of the two.

For most developers building products (not database services), the practical impact either way is minimal. You can embed either one in your app and ship. The question worth asking your legal team is a specific one: do we allow AGPL dependencies? If yes, Redis is back on the table. If no, Valkey is the one that clears the bar.

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, but the implementations differ.
  • Redis 8 folded the old Redis Stack modules into core: JSON, time series, probabilistic data types, the query engine, and vector sets all ship in the base server under the same license as the rest of it. That is a real feature lead for anyone who wanted search or vectors without bolting on a module.
  • Valkey keeps those capabilities as separate modules (valkey-json, valkey-search, valkey-bloom) rather than in core, so you install what you need.

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 the Redis Stack feature set, switching has a real cost. The integrated experience is hard to replicate elsewhere.
  • You want JSON, search, time series or vectors in the base server. Redis 8 ships all of them in core. Valkey has equivalents, but as modules you install and operate yourself.
  • Your legal team allows AGPL dependencies. That is the whole license question now, and for most companies shipping an application rather than a hosted database, the answer is yes.

When to Pick Valkey

Pick Valkey when:

  • Your policy blocks AGPL. Plenty of enterprises ban AGPL dependencies outright rather than argue about where the network-use clause starts. BSD 3-Clause clears that policy without a conversation.
  • You're building infrastructure or platforms. If your platform includes an in-memory store as a component, Valkey's BSD license means no service-offering restrictions and no copyleft to reason about.
  • You want to avoid license risk. The license changed twice in fourteen months. Community governance under the Linux Foundation makes another sudden shift much less likely.
  • You are on AWS. ElastiCache prices Valkey about 20% below Redis OSS on node-based clusters and 33% below on serverless, so the path of least resistance already points there.

Being direct about it: in 2024 I would have said Valkey for anything new, no hesitation. In 2026 it is closer. Redis 8 is open source by the OSI's definition and ships a genuinely larger core. Valkey is the pick when your organization has a rule about copyleft, when you want governance that no single vendor can reverse, or when your cloud already defaults to it. Both are the same store underneath, and neither choice is one you will struggle to undo.

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.

Bringing existing data across is built in: in the create flow, pick Migrating from another platform, then either pull from Upstash with an API key or Vercel KV with its KV_URL, or paste any Redis/Valkey connection string. It reads the source once with a non-blocking scan and copies every key, type, and TTL into a fresh Valkey, so there is no manual RDB step. (See Migrating from Redis to Valkey for the full walkthrough.)

Wrapping Up

The Redis-to-Valkey story has a third act now. Redis changed its license, the community forked it, and then Redis came back to an OSI-approved license with a bigger core than it had before. The fork is still protocol-compatible, so switching either direction requires zero code changes. The deciding factors are copyleft policy, governance, and whether you want the extra data types in core, not technology.

Manage your local instances:

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

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