Skip to content
Back to Projects
miniredis - A Redis-compatible in-memory store built from scratch in C++17 with a non-blocking epoll/kqueue reactor, RESP protocol, skip-list sorted sets, and 984K+ ops/sec throughput by Rutwik Patel

miniredis - Redis-Compatible In-Memory Store

C++17
epoll / kqueue
RESP
Skip List
View Live Project

The Challenge

Redis makes single-threaded, event-driven networking look effortless — but reproducing it from scratch means solving the hard parts yourself: a non-blocking reactor that scales across thousands of connections, a wire protocol parser that handles partial reads, a sorted-set data structure with logarithmic operations, and durability without blocking the event loop. The goal was a from-scratch, Redis-compatible server fast enough to be benchmarked against the real thing.

The Solution

Built a single-threaded, non-blocking reactor in modern C++17 using epoll on Linux and kqueue on macOS behind one portable event-loop abstraction. Implemented a streaming RESP (REdis Serialization Protocol) parser that tolerates partial reads and pipelining, so any redis-cli or Redis client library can talk to it unmodified. Sorted sets are backed by a hand-written skip list giving O(log n) inserts and range queries. Throughput was pushed to 984K+ ops/sec — a 2.5x gain — by sharding locks across key space, and the whole thing is load-tested with a custom Go benchmark harness.

Architecture

Client (redis-cli / any RESP client) → non-blocking epoll/kqueue reactor → streaming RESP protocol parser → command dispatch → data structures (hash table, hand-written skip list for ZSETs) → AOF persistence + pub/sub + replication. Sharded locking across the key space for throughput. Cross-platform event-loop abstraction (Linux/macOS). Go-based load-testing harness.

Impact

  • Reaches 984K+ ops/sec — 2.5x higher throughput via sharded locking
  • Wire-compatible with the RESP protocol: works with redis-cli and standard Redis clients unmodified
  • Hand-written skip list delivers O(log n) sorted-set inserts and range queries
  • Non-blocking epoll/kqueue reactor scales across many concurrent connections on a single thread
  • AOF persistence, pub/sub, and replication implemented from scratch
  • Load-tested end-to-end with a custom Go benchmark harness

What I Learned

  • A streaming protocol parser must treat every read as partial — buffering RESP frames across reads was the difference between "works with one client" and "works under load"
  • Sharded locking across the key space unlocked most of the 2.5x throughput gain; a single global lock left cores idle
  • A hand-written skip list is far simpler to reason about than a balanced tree and hits the same O(log n) bounds Redis relies on for ZSETs
  • Abstracting epoll and kqueue behind one interface kept the core loop identical across Linux and macOS