kevy
A Redis-wire-compatible single-DC key–value server in pure Rust.
Zero crates.io dependencies. Speaks RESP2, so redis-cli,
valkey-cli, and every Redis client library work unchanged.
&
What this gives you
- All five Redis data types (String, Hash, List, Set, Sorted Set) plus
Streams, Pub/Sub, Transactions (
MULTI/EXEC/WATCH/UNWATCH), Blocking pops, and the standard persistence verbs. - A thread-per-core, shared-nothing engine. On Linux the reactor
prefers
io_uring(kernel ≥ 5.19) and falls back to epoll. On macOS/BSD the reactor uses kqueue. - AOF + RDB snapshot persistence. Eight Redis eviction policies.
- 98 commands reply-checked byte-for-byte against valkey 9.1.
- A 768 KB stripped binary that boots into under 5 MB of RSS.
Install
crates.io
Pre-built binaries
Attached to every GitHub Release
for Linux x86_64, Linux aarch64, and macOS Apple Silicon. Each archive
ships the kevy binary, an annotated kevy.toml.example, the README,
and both license files; a matching .sha256 is published alongside.
TAG=v2.0.20
TARGET=x86_64-unknown-linux-gnu # or aarch64-unknown-linux-gnu, aarch64-apple-darwin
|
Docker
Multi-arch (linux/amd64, linux/arm64), published to both registries:
Image defaults: KEVY_BIND=0.0.0.0, KEVY_PORT=6379, KEVY_DIR=/data,
KEVY_AOF=1. Override with -e or by appending flags:
Docker's default seccomp blocks io_uring_setup, so the container runs
on epoll. To enable io_uring for benchmarks:
Quick start
First connection
&
|
Configuration precedence
CLI flags → environment variables → TOML file → built-in defaults.
# env-var equivalents: KEVY_BIND KEVY_PORT KEVY_THREADS KEVY_DIR KEVY_AOF
TOML config example
[]
= "127.0.0.1"
= 6379
= 0 # 0 = auto-detect CPU count
= "/var/lib/kevy"
[]
= true
= "everysec" # "always" | "everysec" | "no"
= 100
= "64mb"
[]
= "1gb"
= "allkeys-lru"
= 5
[]
= true
= "127.0.0.1"
= 9100 # Prometheus scrape: http://host:9100/metrics
The full annotated schema is in
kevy.toml.example.
Unix-domain socket
For same-host clients on Linux, point KEVY_UNIX_SOCKET at a
filesystem path. The server dual-binds TCP and UDS with identical
RESP semantics; UDS is materially faster than TCP loopback at every
workload measured. See docs/uds.md.
KEVY_UNIX_SOCKET=/tmp/kevy.sock
Operations
Graceful shutdown
SIGTERM triggers a drain: stop accepting new connections, flush the
AOF, run a final snapshot when persistence is enabled, then exit.
SIGKILL skips the drain; on next boot the AOF replay resumes from
the last fsync.
Metrics
Set [metrics] enabled = true. The server exposes a Prometheus-format
endpoint at http://<metrics-bind>:<metrics-port>/metrics. Key
exported series:
| Series | Meaning |
|---|---|
kevy_connections_active |
Current open client connections |
kevy_commands_total{cmd=…} |
Per-command command count |
kevy_cmd_latency_ns_bucket{cmd=…} |
Histogram of per-command latency |
kevy_keys_total{shard=…} |
Key count per shard |
kevy_aof_lag_ms |
AOF write-to-fsync lag |
kevy_memory_rss_bytes |
Resident set size |
Backup and restore
backup runs against a live server; restore writes into a fresh
data directory and the server picks the contents up on the next boot.
Cluster routing (single node, key-aware)
--cluster exposes each shard as a virtual cluster node so stock
cluster-aware clients route writes directly to the owning shard.
Topology is reported via CLUSTER SLOTS / SHARDS / NODES; a
wrong-shard key on a cluster port replies -MOVED.
Full guide: docs/cluster.md.
Replication and failover
A kevy server can run as a primary that streams every applied
mutation to N replicas, as a replica that mirrors a primary, or
with kevy-elect integration as a quorum-failover node.
[]
= "primary"
= 16004
# or
= "replica"
= "primary.example:16004"
REPLICAOF / REPLICAOF NO ONE / ROLE retarget and inspect roles
at runtime. Full server + client recipes in
docs/replication.md.
Lua scripting
EVAL, EVALSHA, and SCRIPT LOAD / EXISTS / FLUSH are backed by
the in-house pure-Rust luna
runtime. Default Lua 5.1 (Redis ecosystem compatibility); opt into
5.2 – 5.5 per script with a #!lua version=N shebang. Includes pure-
Rust cmsgpack and cjson standard libraries.
Full reference: docs/lua.md.
Client compatibility
The following client libraries are verified end-to-end against a
default kevy --port 6379 instance, including the script-heavy paths:
| Language | Library | Version |
|---|---|---|
| Java | Jedis | 5.x |
| .NET | StackExchange.Redis | 2.x |
| Go | go-redis | v9 |
| Python | redis-py | 5.x |
| Python | Celery | 5.6 |
| Ruby | Sidekiq | 6.5 |
| Node.js | ioredis | 5.7 |
| Node.js | BullMQ | 5.79 |
| Node.js | Bee Queue | 1.7 |
| Node.js | node-redlock | 5 |
redis-cli and valkey-cli both work out of the box.
What's not supported
| Feature | Why kevy doesn't ship it | Recommended alternative |
|---|---|---|
| AUTH | kevy assumes a trusted network. | Authentication proxy in front of kevy. |
| TLS | Same as AUTH — out of charter. | stunnel / envoy TLS termination. |
Multi-database SELECT |
One keyspace per server. | Run multiple kevy instances on different ports. |
| ACL | Single trust domain. | Authentication proxy. |
| Multi-DC active-active | Single-DC charter. | A KV with explicit multi-region support. |
| Gossip discovery | Topology is declarative. | Operator-managed config. |
| Online resharding | Resharding is offline. | Plan capacity at the cluster boundary. |
The detailed charter rationale lives in
MIGRATION-FROM-VALKEY.md.
Reproducing the benchmarks
Full method and the workload-by-workload table are in
bench/REPORT.md.
Library entry-point
kevy also exposes a Rust library so the server can be started in-
process:
use ;
For embedding the engine without the network reactor at all, use
kevy-embedded instead.
License
Licensed under either of MIT or Apache-2.0, at your option.