Rung 02 · RESP3 spec · In progress
Redis-compatible server
System.IO.Pipelines and back-pressure
Claims, written before the code
- HeldOf the 259 tests real Valkey 9.1.2 passes in
unit/type/incr,unit/type/string,unit/keyspace,unit/expire(suite tagsneeds:debug,needs:repl,needs:resetexcluded), ours passes ≥ 90%, and 100% ofunit/type/incrHeld. 251/259 (96.9%); incr 31/31
- Held
GETon an existing key andINCRon an existing integer, including parse and reply, allocate 0 B per commandHeld. 0 B for 16 pipelined
GETs and 16INCRs - Held
valkey-benchmark -t set,get -n 1000000 -c 50 -P 16reaches ≥ 50% of valkey-server's requests/secHeld. SET 91.7%, GET 82.1% (medians of 3 alternating rounds). But it uses about 4× the CPU. See below.
- HeldAfter loading GeoNames
cities15000into both servers withvalkey-cli --pipe, full dumps are byte-for-byte identicalHeld. 34,432 keys, identical
External judge: Valkey 9.1.2 test suite, run against both servers
96.9%All 259 tests Valkey passes
31/31unit/type/incr
103/104unit/type/string
56/59unit/keyspace
61/65unit/expire
identicalGeoNames dump, 34,432 keys
8 failing tests
- MSETEX keyspace notifications
- COPY basic usage for stream
- COPY basic usage for stream-cgroups
- MOVE basic usage
- import-source can be closed when import-mode is off
- Import mode should forbid active expiration
- Client can visit expired key in import-source state
- Negative ttl will not cause server to crash when import mode is on
Throughput (valkey-benchmark, 50 clients, pipeline 16) and CPU
1.61valkey-server CPU seconds / 2M requests
6.46Our CPU seconds / 2M requests
4.0×CPU cost relative to Valkey
What surprised us
- The judge found two real bugs before it found any missing features.
- One unsupported command can hide 58 passing tests. Without
--durable, the firstPSUBSCRIBEinstring.tclaborted the rest of the file, and the score read 68.7%. The flag is upstream and applies to both servers equally. - Requests per second was the wrong headline. Ours reaches 82–92% of Valkey's throughput while using about 4× its CPU (3.2 µs vs 0.8 µs per request). Command execution is only 1% of the samples; thread-pool spinning (15%) and lock spinning (6%) are larger. Turning the spinning off saves 15% of the CPU; the rest is the cost of three async loops and thread hops per connection, against Valkey's single event loop.
INCRBYFLOAT 10.5then0.1returns10.59999999999999964, and that's correct. Valkey formats with%.17Lf, and on Apple Siliconlong doubleis a plaindouble. Real Valkey on the same Mac gives the same bytes.
Raw evidence
- README.md
- judge/geonames-load-6380.txt
- judge/geonames-load-6390.txt
- judge/geonames-sha256.txt
- judge/suite-ours.txt
- judge/suite-reference.txt
- judge/summary.txt
- evidence/benchmarks.md
- evidence/cpu-experiment.csv
- evidence/throughput-cpu.csv
- evidence/throughput-env.txt
- evidence/throughput-raw.csv
- evidence/throughput.md