Video summary

Implementing Command Pipelining | Redis Internals

Main summary

Key takeaways

Technology

Redis command pipelining (concept)

  • Problem with normal request/response: When a client sends commands one at a time over TCP, each command requires a network round trip (client → server request, server → client response). This becomes a major cost over the internet.
  • Pipelining idea: Instead of sending one command per request, the client sends multiple commands back-to-back in a single request.
    • The server executes them sequentially (command1, then command2, then command3).
    • The server returns multiple responses in the same overall reply.
  • Important note: Pipelining is not a transaction. It’s just multiplexing many commands into one request/response exchange.

Tradeoffs and performance impact

  • Throughput improves: Redis operations are mostly in-memory, so computing each command is very fast (microseconds/nanoseconds). The dominant overhead is network I/O and blocking system calls.
  • Fewer context switches / less waiting on network I/O: With pipelining, the server spends less time alternating between processing and network reads/writes.
  • Memory cost increases: Because responses for all pipelined commands must be sent together, Redis (or the custom implementation) needs to buffer outputs in memory before writing them back.
    • More pipelining → potentially higher memory consumption.

How the video demonstrates pipelining

  • Uses Redis CLI for baseline testing.
  • Then uses netcat with manually crafted RESP payloads (showing $, *, \r\n formatting) to send:
    • ping
    • set k v
    • get k
  • Shows that a single request yields three responses:
    • pong
    • +OK
    • $1 ... v

Implementation guide: adding pipelining to a Redis-like server

Main changes described in the codebase:

  1. Input parsing changes (read side)

    • Previously: decode exactly one command from a network read.
    • Now: decode multiple concatenated RESP commands from the same input buffer.
    • Introduced a concept like Redis CMDS (an array/slice of commands).
    • Decoder modification: the decode function now returns []interface{} / multiple decoded values, iterating until the buffer ends.
    • Uses the delta (number of bytes consumed) to advance through concatenated RESP frames.
  2. Output generation changes (eval/response side)

    • Previously: respond handled one command and wrote its result directly.
    • Now: respond handles multiple commands (even if only one command is present).
    • Evaluation switches from “write immediately” to:
      • evaluate each command
      • buffer each encoded response
      • send all responses in one shot at the end.
  3. Eval functions refactored for pipelining

    • Instead of returning values/errors by writing to the socket directly, eval functions return RESP-encoded response bytes (including encoded error replies like -...).
    • The top-level eval/respond loop appends all results to a buffer (buff.write(...)), then flushes once (c.write(buff.bytes)).
  4. Example behavior inside the loop

    • ping response encoded
    • set k v response encoded
    • get k response encoded
    • All three are written as a single combined response stream.

Testing / verification

  • Runs main.go and connects to a different port (e.g., 7379).
  • Sends the same pipelined command sequence and confirms the combined output:
    • pong
    • +OK (from set)
    • bulk string result for get k

Key takeaway from the tutorial

  • To implement pipelining: keep the internal command execution logic mostly unchanged, and focus modifications on:
    • parsing multiple commands from one read
    • buffering multiple responses
    • sending one combined response
  • Also emphasizes code structuring: making I/O boundaries generic makes adding features like pipelining easier.

Main speakers / sources

  • Speaker: “Atta” (explicitly thanked at the end: “Thanks, Atta.”)
  • Source referenced: Redis RESP protocol (conceptually) and the tutorial’s codebase at github.com/dicedb/dice (specific commit mentioned).

Original video