Redis-Rust
An in-memory Redis-style store in Rust: strings with TTL, lists, sets and sorted sets, served over a Redis-style TCP protocol and a JSON HTTP API.
rust · tokio · axum · serde · ordered-float
Redis-Rust is an in-memory data store inspired by Redis, written in Rust to learn how a database server works from the socket up. It keeps all data in memory and serves it over two interfaces at once: a Redis-style TCP protocol and a JSON HTTP API.
What it supports
| Data type | Commands |
|---|---|
| Strings | SET, GET, DEL, and SET key value EX seconds for expiry |
| Lists | LPUSH, RPUSH, LPOP, RPOP, LRANGE (with negative indices) |
| Sets | SADD, SREM, SISMEMBER, SMEMBERS |
| Sorted sets | ZADD, ZREM, ZRANGE, ZSCORE |
| Utility | PING |
How it's built
- TCP server on port 6379. A Tokio
TcpListeneraccepts connections and spawns one task per client. Each command is read as a line, matched with Rust slice patterns (["SET", key, value, "EX", ttl]), and answered in RESP, the Redis wire format. - HTTP API on port 3000. An axum router exposes the same operations as JSON endpoints, for example
POST /keys/:key,GET /lists/:key/range/:start/:endandPOST /zsets/:key/add. Both servers share oneArc<Database>, so a key written over TCP can be read over HTTP. - One lock per data type. Strings, expiry times, lists, sets and sorted sets each live in their own
HashMapbehind anRwLock, so reads run in parallel and list traffic never blocks string reads. - Lazy expiry.
SET ... EXrecords a deadline, andGETdeletes the key if the deadline has passed. - Sorted sets on two structures. A
HashMapgivesZSCOREits member lookup, and aBTreeSetordered by (score, member) keepsZRANGEin order.ordered-floatmakesf64scores sortable.
Try it
bash
cargo runTalk to the TCP server with netcat:
bash
echo "SET greeting hello" | nc localhost 6379
echo "ZADD scores 100 alice" | nc localhost 6379Or use the HTTP API:
bash
curl -X POST localhost:3000/keys/greeting \
-H "Content-Type: application/json" \
-d '{"value": "hello", "ttl": 60}'
curl localhost:3000/keys/greetingLimitations
- Commands are read as plain lines, not RESP arrays, so
ncworks butredis-clidoesn't yet. Values can't contain spaces. - Data types don't conflict: one key can hold a string and a list at the same time, where Redis would return
WRONGTYPE. - Expired keys are only removed when they're read. There's no background cleanup.
- Nothing is persisted. Restarting the server clears all data.
I wrote about how it works in more detail in Building a Redis clone in Rust.