Blog โ€” Two Techies

Redis vs Valkey vs Dragonfly vs KeyDB vs Garnet: every number, on 48 bare-metal cores

I benchmarked Dragonfly, Redis, and Valkey on 48 real bare-metal cores. Not "X wins" โ€” a quantified trade-off between raw throughput and operational simplicity, with the reproducible harness and raw data.

Three configurations at 48 cores: Dragonfly 15.5M, a Redis cluster driven by a normal client 4.6M, and the same cluster driven per-shard 40.6M ops per second

Throughput vs cores at 48 bare-metal cores: Dragonfly climbs smoothly to 15.5M ops/s, a realistic Redis cluster plateaus near 5M, and the fully-driven cluster ceiling scales to 40.6M

Five in-memory engines, one 48-core bare-metal box, one harness, raw data published. This page has all the numbers on it โ€” throughput, latency, memory, scaling curves, and the caveats that decide whether you should believe any of them. The seven-part series underneath goes deeper on each; the interactive explorer lets you filter the raw runs yourself.

All three are real, measured on the same machine, on the same workload, within minutes of each other. That spread โ€” 9ร— between how a cluster can perform and how a normal client actually drives it โ€” turned out to be the most interesting finding in the whole project, and it is the number most benchmarks quietly pick one side of.

๐Ÿ”ฌ Explore the raw runs yourself

Every number on this page is filterable by engine, core count, workload, value size and pipeline depth in the interactive Benchmark Explorer โ€” 600+ recorded runs, medians computed live, run-health (hit rate, connection errors) shown behind every point. No sign-up, no email. Open the explorer โ†’


Read this before you quote a number

I would rather you trust a smaller claim than repeat a bigger one I can't defend. So, up front:

Hardware, both sessions: AWS c7i.metal-24xl server โ€” bare metal, Intel Xeon 8488C (Sapphire Rapids), 48 physical cores, single NUMA node, 192 GB. Client on its own over-provisioned box, same AZ and placement group, us-east-1. Every run proven server-bound before it counted. Keyspace pre-populated so reads hit real data (hit_rate = 1.0 on every row below). Client-side latency only โ€” never INFO numbers, which are not comparable across these engines.


Table A โ€” Session 1 (Sep 1): Redis, Valkey, Dragonfly

48 cores ยท read-heavy (SET:GET 1:10) ยท 100-byte values ยท pipeline 16 ยท medians of 2 reps (ceiling: 1 rep) ยท latency is client-side, in milliseconds.

Configuration Throughput ops/core p50 p99 p99.9 bytes/key
Redis Cluster โ€” fully driven (per-shard routing) 40.6M 845K 0.56 1.51 4.64 165.3
Valkey Cluster โ€” fully driven 40.2M 837K 0.57 1.32 3.50 168.7
Dragonfly โ€” one process 15.5M 322K 0.88 2.42 3.33 146.1
Redis Cluster โ€” realistic (one normal client) 4.6M 95K 83.97 138.24 150.53 165.3
Valkey Cluster โ€” realistic 4.5M 94K 85.76 140.80 157.70 168.7

Three things fall out of that table:

  1. Dragonfly is 3.4ร— a realistic cluster for one process and no sharding, and reaches 38% of the raw ceiling for near-zero operational effort.
  2. The realistic cluster's tail is catastrophic โ€” 84ms p50 against Dragonfly's 0.88ms. That isn't the server being slow; it's requests queuing client-side because one cluster-mode client can't keep 48 shards busy. The same cluster, driven per-shard, does 0.56ms p50.
  3. Dragonfly is ~12โ€“13% leaner in memory (146 vs 165/169 bytes/key). Of everything here, this is the number least sensitive to how you run the test.

Scaling: the three shapes

Read-heavy, pipelined, Mops/s by core count. This is the chart that matters more than any single figure.

series 4c 8c 16c 24c 48c
Dragonfly 2.0 3.7 6.5 9.0 15.5
Redis (realistic client) 3.2 5.0 5.0 4.8 4.6
Redis (fully driven) 5.2 9.2 15.8 22.5 40.6
Valkey (realistic client) 3.1 4.9 4.9 4.8 4.5
Valkey (fully driven) 5.0 8.8 15.2 21.7 40.2

Dragonfly climbs. The driven ceiling climbs faster. The realistic cluster stops improving at 8 cores and then very slightly declines โ€” adding shards past that point made a normal client worse, not better. Dragonfly overtakes the realistic cluster at about 16 cores.

Why a normal cluster-mode client leaves a Redis cluster roughly 9x under-driven, with shards sitting idle

Full story โ†’ Part 3: Why a normal client gets 4.6M out of a cluster that can do 40M

Latency under load

p50, p99 and p99.9 latency at 48 cores: Dragonfly and the driven cluster sub-millisecond, the naive cluster client ballooning past 80ms

Dragonfly and a well-driven cluster are both sub-millisecond at p50. A naive cluster client is ~95ร— worse, and that gap is client-side queuing, not server work. โ†’ Part 4: Latency under load

Memory efficiency

Bytes per key at 1M keys of 100 bytes: Dragonfly 146, Redis 165, Valkey 169

1M keys ร— 100B, baseline-subtracted: Dragonfly 146.1 ยท Redis 165.3 ยท Valkey 168.7 ยท KeyDB 200.3 bytes/key. Hardware-independent and the least disputable number in the project. โ†’ Part 5: Memory efficiency

The cross-key tax

Multi-key throughput: Dragonfly runs MGET and MSET across the keyspace freely while Redis and Valkey clusters reject cross-slot keys

This is Dragonfly's structural advantage and it has nothing to do with ops/s. On a Redis or Valkey cluster, plain multi-key operations across the keyspace are rejected outright:

MGET alpha bravo charlie      -> CROSSSLOT Keys in request don't hash to the same slot
EVAL over 3 plain keys        -> CROSSSLOT Keys in request don't hash to the same slot
MGET {u1}:a {u1}:b            -> OK     (hash-tagged, same slot)

Dragonfly runs all three freely as one process: MGET(10) at 2.4M ops/s, MSET(10) at 1.3M ops/s at 48 cores. On a cluster, the cost isn't latency โ€” it's redesigning your key names around hash tags, forever. โ†’ Part 6: Operational simplicity, quantified


Table B โ€” Session 2 (Sep 9): KeyDB and Garnet

Different load generator (AMD c7a.24xlarge), so these are only comparable to each other, not to Table A. The same-day Redis reference figures and why they moved are in the KeyDB/Garnet write-up.

KeyDB plateaus and refuses to start above 16 threads while Garnet scales almost linearly past 21M ops/s

Configuration Throughput p50 p99 bytes/key
Garnet โ€” one process, 48 cores โ‰ฅ21.4M (client-limited) 0.68 1.63 not measured
KeyDB โ€” one process, 16 threads (its maximum) 636K 22.85 64.26 200.3

KeyDB found a wall, not a slope

cores 4 8 16 24 48
KeyDB ops/s 413K 569K 636K won't start won't start
KeyDB p50 (ms) 28.86 22.78 22.85 โ€” โ€”

Doubling from 8 to 16 cores bought 12% โ€” the signature of lock contention. And above 16 threads KeyDB 6.3.4 doesn't slow down, it refuses to boot:

*** FATAL CONFIG FILE ERROR (KeyDB 6.3.4) ***
'server-threads "24"'
Invalid number of threads specified

On a 48-core box, KeyDB's multithreading tops out at a third of the machine, at 22โ€“29ms p50 while it does it. It is the clearest answer I've found to "why did Dragonfly rewrite from scratch instead of just doing what KeyDB did?" โ€” the fork approach ran out of runway.

Garnet scaled further than I expected

cores 4 8 16 24 48
Garnet ops/s 4.1M 8.1M 15.8M 19.0M 21.4M+
Garnet p50 (ms) 3.39 1.72 0.78 0.60 0.68

Near-linear to 16 cores, still climbing at 48, sub-millisecond p50 from 16 cores on. I checked server CPU on every run before believing it โ€” at 24 cores it peaked at 2204% of a 2400% budget, at 48 cores ~4000% of 4800%, comfortably inside its pinned cores, hit rate 1.0 throughout. Then the client saturated, so 21.4M is where my load generator gave up, not where Garnet did.

Microsoft's .NET engine deserves far more independent benchmarking than it gets. โ†’ Full write-up: KeyDB and Garnet


So which one should you run?

Decision view: the three-way trade-off between raw throughput, operational effort and memory efficiency

If this is your situation Run this Why
One big box, want the cores used, don't want to operate a cluster Dragonfly 3.4ร— a realistic cluster, one process, multi-key just works
Already on Redis, throughput is fine, you value the ecosystem Stay on Redis The engine is rarely the bottleneck โ€” check your client first
Licensing/governance matters more than the last 2% Valkey Measured within noise of Redis on every axis here
You need absolute peak and can build per-shard routing Redis/Valkey Cluster, driven properly 40M is real โ€” but you must earn it client-side
Memory cost per key dominates your bill Dragonfly 12โ€“13% leaner, and it's the most robust number here
On .NET, or willing to run something newer Evaluate Garnet Scaled furthest of anything I tested; verify it yourself
Considering KeyDB in 2026 Don't, without testing Hard 16-thread cap, weak scaling, heaviest memory

The honest headline is not "X wins." It's that on modern many-core hardware the shape of the scaling curve, and how hard the engine is to drive properly, matter more than any single ops/s number. โ†’ Part 7: When to use which


Reproduce it, and tell me where I'm wrong

That's the whole point of publishing the harness.

git clone https://github.com/sunnysahijwani/dragonfly-redis-valkey-benchmark
cd dragonfly-redis-valkey-benchmark

# single box, quick run (Docker required)
bash scripts/run-phase-a.sh

# the fully-driven cluster ceiling
bash scripts/cluster-saturate.sh redis <server-ip> 7001 <shards>

# regenerate every table above from the raw data
python3 analysis/analyze-aws.py

Pinned versions: Redis 8.2.8 ยท Valkey 8.1.9 ยท Dragonfly v1.40.1 ยท KeyDB 6.3.4 ยท Garnet 2.1.6 ยท memtier_benchmark 2.5.1 โ€” all images pinned by digest, every knob recorded per row. Raw data: results/runs-aws.csv (350 runs) plus the session-2 capture โ€” re-derive every number on this page. Repo: github.com/sunnysahijwani/dragonfly-redis-valkey-benchmark (MIT)

The methodology traps that make most in-memory benchmarks lie, and how each was disarmed

If you only read one part of the series, read the methodology โ€” including the bias I caught in my own setup, where a false reading was off by 350ร— on the same machine. โ†’ Part 1: How I kept it honest


The full series

  1. How I kept it honest โ€” methodology & fairness โ€” the traps that make most in-memory benchmarks lie, and how I disarmed each one. Start here.
  2. Throughput & scaling on 48 cores โ€” the full setup, every config and tweak, and the chart where three completely different shapes appear.
  3. Why a normal client gets 4.6M out of a cluster that can do 40M โ€” a debugging story that became the most interesting finding.
  4. Latency under load โ€” p50/p99/p99.9, and why the naive-cluster tail explodes.
  5. Memory efficiency โ€” bytes per key; the least-disputable number in the series.
  6. Operational simplicity: the cross-key tax โ€” cross-slot, hash tags, multi-key and Lua, quantified.
  7. When to use which โ€” the decision table and the three-way trade-off.

Follow-ups: KeyDB and Garnet on the same harness ยท How long a Redis Sentinel failover actually takes ยท the interactive explorer

Methodology reviewed against the DragonflyDB team's benchmarking notes before publishing. Benchmarked on AWS c7i.metal-24xl (48 physical Sapphire Rapids cores) with a dedicated client instance, us-east-1, same placement group.


About the author

I'm Sunny Sahijwani โ€” a senior backend & DevOps engineer.

๐Ÿ‘‰ Connect with me on LinkedIn โ€” I'm always happy to talk in-memory databases, performance, and systems architecture.

The full harness, pinned versions, and raw data for this benchmark are public on GitHub โ€” rerun it and tell me where I'm wrong.

More from Two Techies

Or read the case studies โ†’