Proves it is correct. Measures that it is fast.
An in-memory key-value store that speaks the Redis protocol. Deterministic by construction, benchmarked with the method beside every number.
- Rust
- RESP2
- Apache-2.0 / MIT
- single binary
curl -fsSL https://seedstone.io/install.sh | sh
macOS and Linux, x86_64 and arm64. Verifies the release's SHA-256 before installing. Read it first: install.sh.
Fast · KEYS over 7 000 keys, ops/s
5.16× the throughput of Redis on a page cache's walk
Same machine, same client, median of three · every cell and the method: benchmarks →
Install
One line. Or any of five others.
The binary is the same on every channel. The packages start a service on loopback; after Homebrew or Cargo, start it with seedstone.
curl
curl -fsSL https://seedstone.io/install.sh | sh
macOS and Linux, x86_64 and arm64. Verifies the release's SHA-256, installs the binary, nothing else.
Docker
docker run -p 6379:6379 seedstone/seedstone --bind 0.0.0.0:6379 --no-auth
Also on GHCR.
Homebrew
brew install seedstonelabs/tap/seedstone
macOS and Linux; as a service with brew services.
Cargo
cargo binstall seedstone
The release archive in seconds; cargo install builds from source.
deb / rpm
A .deb or .rpm with a systemd unit, from the release page; what the service does.
Helm
helm install seedstone oci://ghcr.io/stefanobaldo/charts/seedstone --set auth.noAuth=true
The chart, and what auth.noAuth says.
$ redis-cli127.0.0.1:6379> set greeting hello ex 60OK127.0.0.1:6379> ttl greeting(integer) 60127.0.0.1:6379> get greeting"hello"127.0.0.1:6379>
Every channel, with checksums, the packaged defaults and the service units: docs/install.md
Correct
The same seed, the same bug. Every time.
The whole server runs inside a deterministic simulation: a virtual clock, a simulated network, scheduled clients. Every completed command folds into a trace hash that depends on two seeds and nothing else.
- seed 0x4f2a9c1e
- virtual clock
- simulated network
- scheduled clients
- trace 0x8b…31
A concurrency bug, the usual way no seed
- run 1✗ tick 6
- run 2passed
- run 3passed
- run 4✗ tick 9, elsewhere
Seen once, gone under the debugger, back in production.
In seedstone seed 0x4f2a9c1e
- run 1✗ tick 18 · 0x8b…31
- run 2✗ tick 18 · 0x8b…31
- run 3✗ tick 18 · 0x8b…31
- run 4✗ tick 18 · 0x8b…31
run 4 on another machine, in a fresh process
✓ Reproduced from the seed, byte for byte. Fixed once.
- 14 / 14
defects planted in the server itself, each caught by the counter that owns it
- 2 seeds
are all a trace hash depends on: the simulation's and the workload's
- every change
that touches code is swept across seeds in CI, and a failure arrives with its seed
How it is built and how it is tested: docs/testing.md
Fast
Ahead of Redis where a cache lives.
Same machine, same client, median of three runs, throughput in operations per second. Every bar is an engine this server is ahead of; the grey line names the ones level with it.
SET 64 B with EX 60 · depth 64 a cache write with a deadline
Dragonfly reads 4.63 M, level with seedstone: the client's ceiling
2.96× Redis at one I/O thread
SET 64 B · depth 64 the plain cache write
Dragonfly 4.65 M and Garnet 4.63 M, level with seedstone: the client's ceiling
2.21× Redis at one I/O thread
MGET 16 keys · depth 64 the multi-key read
Garnet reads 629 k, level with seedstone
1.86× Redis at one I/O thread
GET 64 B · depth 64 the pipelined read
Dragonfly reads 4.65 M, level with seedstone: the client's ceiling
1.75× Redis at one I/O thread
v0.3.2 on a GCP c4a-standard-16, against Redis 8.10.0, Valkey 9.1.1, Dragonfly df-v1.40.2 and Garnet 2.1.5, 2026-10-11. Every cell at every depth, the CPU per operation, the method fixed before the run, and what the numbers do not say: docs/benchmarks.md
Operated
Says only what it can state truthfully.
Built to be run by someone who is paged for it. A stock Prometheus exporter scrapes it in CI.
INFO, without the fiction
Sections that carry only what the node can state: no resident-set figure it would have to guess, no fork it does not have.
# Memory
maxmemory_policy:allkeys-lru
# Persistence
loading:0
aof_enabled:1
fsync_policy:interval
aof_last_write_status:ok
refusing_executors:0
One JSON line per event
Every line opens with a time, a level and the event's name; a monitor selects by evt and reads fields by name, with no parser of its own.
{"ts":1757800000000,"level":"info","evt":"listening","version":"0.1.1","bind":"0.0.0.0","port":6379}
{"ts":1757800000317,"level":"warn","evt":"error_reply","code":"ERR","cmd":"flushall","msg":"ERR unknown command 'flushall'"}
A password that rotates without a restart
Two passwords are valid while the file holds two, so the server and its clients never have to change in the same moment.
- 1add the new line,
SIGHUP - 2move the clients, any pace
- 3drop the old line,
SIGHUP
{"ts":1757800003250,"level":"info","evt":"password_reloaded","passwords":2}
A disk that fails is met with refusal
A write the node cannot keep is not acknowledged: writes are refused until a snapshot is durable, reads are served, and a full disk asks for space, not for a restart.
# the disk is full, --fsync always
> SET order:9 paid
-MISCONF Errors writing to the log: writes are refused until a snapshot is durable
# space freed, a snapshot durable: refusal_ended
> SET order:9 paid
+OK
Flags, output, signals, the password, persistence and INFO: docs/operations.md
Compatibility
A named list. Nothing answered approximately.
RESP2 over TCP, so redis-cli and the ordinary client libraries connect unmodified. Anything outside the list is refused with an error naming the command.
Strings
- GET
- SET
- SETEX
- SETNX
- PSETEX
- MGET
- INCRBY
- STRLEN
- TYPE
Keys & expiry
- DEL
- EXISTS
- EXPIRE
- PEXPIRE
- EXPIREAT
- PEXPIREAT
- PERSIST
- TTL
- PTTL
- SCAN
- KEYS
- DBSIZE
- FLUSHDB
Server
- PING
- ECHO
- AUTH
- HELLO
- INFO
- CONFIG GET
- SLOWLOG
- LATENCY
- COMMAND
- CLIENT
- QUIT
Persistence
- SAVE
- BGSAVE
- LASTSAVE
- SHUTDOWN
Not here yet — next: hashes, lists, sets, sorted sets, Pub/Sub, RESP3
- HSET
- LPUSH
- SADD
- ZADD
- PUBLISH
- MULTI
- EVAL
- SELECT
- replication
- clustering
127.0.0.1:6379> set k vOK127.0.0.1:6379> hset h f v(error) ERR unknown command 'hset'127.0.0.1:6379> hello 3(error) NOPROTO unsupported protocol version127.0.0.1:6379>
Every command, every option, every refusal and every deliberate difference from Redis: docs/compatibility.md
Get started
Try it in the time it takes to read the script.
The installer is the only thing between you and a running server, and it is meant to be read.
curl -fsSL https://seedstone.io/install.sh | sh
Verifies the SHA-256 first · read install.sh · or star it on GitHub