Skip to content

learnwithparam/build-your-own-redis-elixir

Repository files navigation

Build your own Redis in Elixir

Sibling to the Python, Go, Node.js, Rust, and Ruby workshops. Same architectural progression, idiomatic Elixir on the BEAM: gen_tcp, processes, GenServer, Registry, OTP supervision.

The build

# Step Elixir idiom
01 TCP echo :gen_tcp + spawn per connection
02 RESP parser binary pattern matching
03 GET / SET Agent + case/when dispatch
04 Expiry GenServer + monotonic_time
05 AOF persistence File.open(:append) + replay flag
06 RDB snapshots :erlang.term_to_binary + atomic rename
07 Pub/Sub Registry + send/2
08 Replication Registry fan-out + SYNC bootstrap
09 Graceful shutdown trap_exit + terminate/2 callback
10 Capstone benchmark sequential RESP load + percentile report

Each step folder ships with server.exs, README.md, GUIDE.md, EXERCISES.md. A shared lib/resp.ex carries the parser/encoder for modules 04+.

Getting started

Requires Elixir 1.14+.

git clone https://github.com/learnwithparam/build-your-own-redis-elixir.git
cd build-your-own-redis-elixir
make 01-tcp-echo

In another terminal:

nc localhost 6380
> hello
< hello

Run any step

make 01-tcp-echo
make 02-resp-parser
make 03-get-set
make 04-expiry
make 05-aof-persistence
make 06-rdb-snapshots
make 07-pubsub
make 08-replication             # master on 6380; replica with: elixir 08-replication/server.exs replica 6381 127.0.0.1 6380
make 09-graceful-shutdown
make 10-capstone                # benchmark vs real Redis on 6379
make test                       # syntax check + doc check

Why Elixir

Erlang/OTP was built for telephony. Decades later, the same primitives - cheap processes, mailboxes, supervisors - are exactly what a Redis-shaped service wants:

  • Process per connection: tens of thousands of concurrent clients is normal
  • Registry: pub/sub and replication fan-out in 3 lines instead of 30
  • Binary pattern matching: the RESP parser reads like a spec
  • GenServer: state machine semantics without writing one
  • trap_exit + terminate/2: graceful shutdown without manual semaphores
  • :erlang.term_to_binary: zero-ceremony serialization

This is the cleanest sibling of the series. The actor model is doing work other languages have to assemble by hand.

Sibling workshops

Concept Python Go Node Rust Ruby Elixir
Concurrency Threads/selectors Goroutines Event loop tokio tasks Threads Processes
Shared state dict + lock sync.RWMutex Map Arc<Mutex> Hash + Mutex GenServer state
Pub/Sub fan-out List + lock Buffered chan Set broadcast channel Queue per sub Registry + send/2
Sum type duck typing interface{} discriminated objects enum tagged array tagged tuple

License

MIT.

About

Build your own Redis in Elixir — 10 incremental steps on the BEAM, sibling of Python/Go/Node/Rust/Ruby workshops

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors