Case study · P/01 · Systems engineering · C++
mini-redisA Redis-compatible server in C++, built on raw sockets
A key-value server written from scratch in 594 lines of C++, with no framework and no third-party dependencies: a single-threaded, non-blocking epoll event loop over raw POSIX sockets, driven by the stock redis-cli and redis-benchmark tools.
- GET requests / sec at 128-deep pipelining
- 2.7M+
- SET + GET / sec · 50 clients · 1 core
- 150K+
- Redis-compatible commands
- 18
Why build it
I wanted to understand what happens below the API: how a server accepts connections, reads bytes off the wire, parses a protocol and answers, and what it takes to stay fast when hundreds of requests arrive in a single read.
Redis was the right target because its behaviour is fully specified by real tools. If stock redis-cli and redis-benchmark work against my server unchanged, the implementation is honest.
What I built
- TCP server on raw POSIX sockets:
socket,bind,listen,accept, with every client socket set non-blocking. - A single-threaded epoll event loop, the same concurrency model Redis itself uses, so there are no locks on the data path.
- A RESP parser that buffers partial frames per client, so pipelined commands survive split TCP reads, plus inline commands.
- An in-memory store with expiry:
SETwithEX/PX,EXPIRE,TTL,PTTL,PERSIST,INCR. - Pub/sub:
SUBSCRIBE,UNSUBSCRIBE,PUBLISH.
Engineering decisions
The hardest bug class in a network server is assuming one recv() equals one command. It does not: under pipelining a single read can hold dozens of commands, and a command can be split across reads. The parser keeps a per-connection buffer, consumes only complete frames and leaves the rest for the next read.
The benchmark is part of the repository. A script runs redis-benchmark against the server and asserts a floor on every figure, so the published numbers are reproducible rather than a screenshot.
Results
- 150K+ SET and GET requests per second across 50 concurrent clients on a single core.
- 2.7M+ GET and 2.4M+ SET requests per second at 128-deep pipelining.
- 1,000 of 1,000 pub/sub messages delivered under test.
Supported commands
PING ECHO QUIT SET GET DEL INCR EXPIRE TTL PTTL PERSIST EXISTS KEYS DBSIZE FLUSHALL SUBSCRIBE UNSUBSCRIBE PUBLISH
g++ -O2 -std=c++17 -o mini-redis server.cpp ./mini-redis redis-cli set name paritosh redis-cli get name
Stack
- C++17
- POSIX sockets
- epoll
- RESP
- Linux
- redis-benchmark