L33T KV

A KV store that beats Redis 6.0

root@l33t:~$ ./bench --servers 3 --ops 300000

throughput   36,234 ops/sec
avg latency  0.080 ms
beating redis 6.0 (35,670 ops/sec)

root@l33t:~$ _

Four iterations and the true bottleneck discovery.

The setup

A 19-byte binary instead of human-readable text.

A key-value store is a brutally simple thing. Two verbs: SET and GET. The interface is so small that almost all of the cost lives in the wire and the network.

Most KV stores reach for Redis's RESP, a human-readable text protocol that costs seventeen to twenty-three bytes of framing per op. L33T spends three. One byte for the opcode, two bytes for a big-endian length, then the payload. The receiver is a machine. Humans don't need to read it.

Try it. The panel on the right runs your command through the same WASM-compiled parser the server uses. Click Run and watch it break the bytes apart.

type a command, hit Run, see the wire bytes
$
key max 64 bytes, value max 192 bytes - this command: 15 bytes on wire
click Run to encode the command into the L33T wire format.

Python asyncio

The reference baseline. Whatever you do next, you compare against this.

Vanilla asyncio, dict-backed store, one server per port behind a client-side modulo shard. Three shards, three benchmark threads, one hundred thousand ops each. Sync per op, no pipelining. The numbers come back honest.

Result: 0 ops/sec.

Everything that follows is an argument about where the missing throughput went.

root@l33t:~$ _
root@l33t:~$

uvloop + tightened Python

Swap the event loop. Cache the struct. Local-bind the hot-path globals.

uvloop swaps asyncio's event loop for one built on libuv. The wire format stays the same and the loop just dispatches faster. After that comes a round of tightening: cache the struct.Struct so it is parsed once, use readexactly instead of a hand-rolled read loop, and local-bind the hot-path globals so the bytecode emits LOAD_FAST instead of LOAD_GLOBAL.

Result: 0 ops/sec. A 2.3x lift without leaving Python.

Most of the gain was the loop. Some of it was the bytecode. None of it was rethinking the design.

root@l33t:~$ _
root@l33t:~$
root@l33t:~$

C epoll

Hand-written hashtable. Edge-triggered epoll, drain to EAGAIN. No allocator surprises.

The server is about four hundred lines of C. The hash table uses with open addressing and linear probing, with tombstones to mark deleted slots. Each connection has its own read and write buffers. The epoll loop runs in edge-triggered mode and drains every socket until the kernel returns EAGAIN. The listening socket has TCP_NODELAY set so the kernel does not hold packets waiting for more payload.

Result: 0 ops/sec.

From here on, tightening server code does almost nothing. The bottleneck has moved off-chip. Drag the slider on the right. The throughput number is computed from real CPU cost measured in a WASM build of the same hashtable, plus whatever RTT you dial in. Watch what dominates as you change just the network.

drag the RTT - watch what dominates
RTT 1 ms200 ms
80 ms
estimated throughput
----ops/sec
per-op time = cpu + bandwidth + RTT. only RTT changes.
cpu work(loading)measured once in WASM (constant)
bandwidth0.00018 ms8 B value at 1 Gbit (constant)
network RTT80 msyou control this
bottleneck: network

io_uring

The fancy thing that gave nothing.

Same hashtable, same protocol. Replace epoll with io_uring. Try SQPOLL. Try larger ring sizes. The number does not move.

Why: the workload is synchronous per op, in-flight depth is around three, there is no batching to amortize. io_uring's whole pitch is amortizing syscall cost across many in-flight ops. We don't have many in-flight ops.

Knowing when not to use the fancy thing is the lesson. The bottleneck moved off-chip two ceilings ago. The CPU has nothing left to give.

root@l33t:~$ _
root@l33t:~$

The comparison: Redis 6.0

Same lab, same wire, same workload shape. Different protocol, different server.

Three Redis instances run on the same host with persistence turned off. The benchmark uses the native redis-benchmark client so Python overhead is removed from both sides of the comparison. Value sizes range from 8 B to 1 KB.

L33T KV wins at every size in the sweep. At 8 B the lead is 1.6 percent. At 1 KB it shrinks to 0.7 percent. Run-to-run variance is on the order of half a percent, so the smaller leads are effectively ties.

Per-node on loopback, Redis is roughly twice as fast as L33T KV. That gap is what fifteen years of allocator and string work buys. On the LAN, the network absorbs it.

throughput by value size (ops/sec, higher is better)
L33T KV (epoll)Redis 6.0
8 BL33T KV 36,234 / Redis 35,670
100 BL33T KV 35,966 / Redis 35,277
1024 BL33T KV 32,046 / Redis 31,812
3-node, LAN cross-machine, sync per op. native redis-benchmark client to remove Python overhead from both sides.

We beat Redis... But at what cost?

36,234 ops/sec to Redis 6.0's 35,670. A 1.6 percent edge that vanishes the moment you ask L33T KV to do anything Redis was actually built to do. Here is what got cut to claim those numbers.

What you give up to get the speed.

check each feature you would need in production. the verdict updates live.
L33T has itL33T lacks it
L33T KV strengths you need0 of 4
L33T KV gaps you need0 of 7
Tell me what you need.
Check the features your workload requires. The verdict updates live.

What this taught me.

The wire protocol matters less than you would think.
RESP costs five to seven times the framing per op that our three-byte format does. At the LAN-RTT ceiling that difference disappears. The win you can measure isn't always the win that matters.
CPU is rarely the bottleneck once a real network is in the loop.
Three rewrites moved the server from thirteen thousand ops per second to thirty-six thousand. At five microsec of CPU per op against eighty microsec of LAN RTT, anything you do to the CPU side is shaving margins on a number that's already small.
Knowing when to stop optimizing is harder than starting.
io_uring gave nothing because there were no in-flight ops to amortize. The correct response to a fancy tool that doesn't help is to put it down, not to keep tuning parameters until something moves.
Fifteen years of operational hardening beats one weekend of micro-optimization.
Features you don't have are only valuable if you don't need them. The day L33T KV needs to survive a process restart is the day it stops being a benchmark and starts being a database, and that is a different project.

Postscript: a class win.

The store was the final project in a graduate Cloud Computing class. Twelve teams ran the benchmark on the same lab. We took first place at 36,200 ops per second: thirty-four percent ahead of second, and roughly four times the median team.

Class leaderboard with our team in first place at 36,200 ops/sec, 0.08 ms average latency
graduate Cloud Computing class, final ranking

L33T KV.
A KV store that beats Redis 6.0 by sacrificing everything Redis spent fifteen years building.