Skip to content

Latest commit

 

History

History
77 lines (52 loc) · 3.65 KB

File metadata and controls

77 lines (52 loc) · 3.65 KB

progress-banner

Build Your Own Redis in Python — a working Redis server clone from scratch

A single-file Redis reimplementation in pure Python that speaks the real RESP protocol and serves the commands a real Redis client expects: strings, lists, streams, transactions, replication, RDB persistence, pub/sub, and ACL-based authentication. No redis-py, no server frameworks — just the Python standard library.

Built in under 48 hours with Claude Code while reaching CodeCrafters Python leaderboard rank #13.

If you searched for "build a Redis clone in Python", "RESP protocol implementation", "Redis from scratch tutorial", or "Redis internals in Python" — this repo is a complete, readable reference.


What this actually does

A real redis-cli can connect to this server and it just works:

$ ./your_program.sh --port 6380 &
$ redis-cli -p 6380 SET hello world
OK
$ redis-cli -p 6380 GET hello
"world"
$ redis-cli -p 6380 XADD stream '*' temp 36
"1744000000000-0"

Implemented features

  • RESP2 protocol — parser and encoder (simple strings, errors, integers, bulk strings, arrays, nulls) used for both clients and replication
  • Core commands: PING, ECHO, SET (with PX/EX/NX/XX), GET, DEL, EXISTS, INCR, DECR, TYPE, KEYS, CONFIG GET
  • Lists: RPUSH, LPUSH, LRANGE, LLEN, LPOP, BLPOP with real blocking semantics
  • Streams: XADD, XRANGE, XREAD (including BLOCK and $ for new entries)
  • Transactions: MULTI / EXEC / DISCARD with WATCH / UNWATCH optimistic locking (EXEC aborts if a watched key changed)
  • Pub/Sub: SUBSCRIBE, UNSUBSCRIBE, PUBLISH, PSUBSCRIBE
  • Replication: master + replica roles, full handshake (PING → REPLCONF → PSYNC), RDB transfer, command propagation, replica ACK tracking, WAIT
  • Persistence: reads an RDB file at startup (--dir / --dbfilename)
  • Expiry: per-key TTL, enforced lazily on access
  • ACL: ACL SETUSER, DELUSER, USERS, GETUSER, AUTH with SHA-256 password hashes

How it's built

  • Thread-per-connection concurrency model using threading.Thread, with a global store dict guarded by a Lock + a Condition for blocking commands (BLPOP, XREAD BLOCK)
  • RESP streaming parser so a replica can consume back-to-back commands off the master link
  • Replication is just another client — the same parser/encoder drives the master→replica command stream
  • Optimistic locking — each write bumps a per-key version; EXEC validates watched versions before running queued commands

All ~1.5k lines live in a single file (app/main.py) so you can read it front-to-back.


Run it

# Standalone
./your_program.sh --port 6379

# Leader + follower (two terminals)
./your_program.sh --port 6379
./your_program.sh --port 6380 --replicaof "localhost 6379"

# Load an RDB snapshot on startup
./your_program.sh --dir /tmp --dbfilename dump.rdb

Requires uv and Python 3.14.


Why this repo is worth reading

Most "Redis from scratch" posts stop at PING/GET/SET. This one keeps going through the parts that make Redis interesting — blocking commands, stream blocking with $, the PSYNC handshake, RESP quirks, WATCH/EXEC semantics — and keeps the whole implementation in one reviewable file.


Credits

Part of the CodeCrafters "Build Your Own Redis" challenge. If you want to try it yourself, the platform is excellent.