Capstone: Benchmark against real Redis

Elixir lands above Ruby/Python, comparable to Node, below Go/Rust. GenServer.call adds ~1us per op vs direct ETS. The ETS exercise closes most of the gap.

10-capstone/bench.exs
elixir
{sets, buf} = Enum.reduce(0..(n - 1), {[], buf}, fn i, {acc, b} ->
  ts = now_us()
  :gen_tcp.send(sock, encode_array_strings(["SET", "k:#{i}", "v:#{i}"]))
  b2 = read_reply(sock, b)
  {[now_us() - ts | acc], b2}
end)

Sequential RESP load. One socket, N SETs then N GETs.

Elixir on the throughput chart

GenServer-backed Elixir: comparable to Node. ETS-backed Elixir: comparable to Go.

How to close the gap: ETS instead of GenServer (~2x on GETs), Ranch or ThousandIsland for the acceptor (more performant accept loop), pipelined client, NIFs for the parser (the Erlang equivalent of bytes::BytesMut).

Quiz: Quiz

Loading practice…