Video summary

Event Loops Internals And How Redis Handles Multiple Connects on a Single Thread | Redis Internals

Main summary

Key takeaways

Technology

Problem

A prior (single-threaded) Redis-like “radius” implementation couldn’t handle concurrent clients.

Solution concept

Use asynchronous I/O / I/O multiplexing (the core of event loops) instead of creating one thread per connection.


Traditional approach (threads per connection)

When a client connects, the server spawns a new thread and that thread handles the socket.

  • Threads can run concurrently across CPU cores, so the server isn’t fully blocked by I/O waits.
  • Key challenges:
    1. Thread safety / shared state races Example: a shared global count++ is not atomic, so concurrent updates can lose increments.

      • Fix requires mutexes/semaphores to protect critical sections.
        1. Performance & complexity costs Threads can still stall waiting on locks, even though scheduling could otherwise run them. Code also becomes more complex because developers must reason about multi-threaded correctness.

Event loop model (single-threaded, async I/O multiplexing)

The event loop is not a separate process and not a separate thread (even though it supports “concurrency”).

  • It’s described as a thin layer that relies on the kernel + system calls to know when I/O is ready.
  • Event loops (Python async, JavaScript/event loops, libuv/libevent/ev*, Redis internals) ultimately use the same OS mechanism via syscalls.

OS-specific readiness mechanisms (system calls)

Depending on the OS, the event loop uses:

  • Linux: epoll
  • BSD/macOS: kqueue (kq)
  • Windows: IOCP

How epoll works (internal mechanics described)

Core idea

Monitor many file descriptors for readiness (I/O events).

  • In Unix-like systems, “everything is a file,” and each I/O object has a file descriptor—not only disk files, but also sockets.

Main syscalls mentioned

  1. epoll_create1 — create an epoll instance
  2. epoll_ctl — register file descriptors to monitor (server socket + client sockets)
  3. epoll_wait — block until one or more file descriptors are ready

Event loop flow

  • Run an infinite loop:
    • call epoll_wait to learn which descriptors are ready
    • for ready descriptors: perform read/write (or accept, process, respond)
    • if nothing is ready: epoll_wait keeps waiting, so the single thread doesn’t busy-wait

Why this enables concurrency without threads

  • The kernel receives network packets into kernel buffers and can notify which socket/process has data ready.
  • The event loop uses readiness notifications so the single thread only performs I/O operations when they won’t block.
  • Framed as the “heart and soul” of async programming/event loops: kernel tells user space when I/O is available.

Redis-specific goal (next step)

The next video is promised to:

  • implement an event loop
  • build a Redis server that can handle concurrent clients (e.g., two clients communicating simultaneously)
  • run a benchmark simulating 10,000 commands over 200–300 concurrent clients
  • compare performance against a Go implementation and the actual Redis behavior

Main speakers / sources

  • Speaker: Video narrator/instructor (single presenter; no named individuals provided in the subtitles)
  • Source of technical mechanism: Operating system kernel event notification APIs (epoll, kqueue, IOCP) referenced by the speaker

Original video