Video summary
Event Loops Internals And How Redis Handles Multiple Connects on a Single Thread | Redis Internals
Main summary
Key takeaways
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:
-
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.
- 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.
- Fix requires mutexes/semaphores to protect critical sections.
-
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
epoll_create1— create an epoll instanceepoll_ctl— register file descriptors to monitor (server socket + client sockets)epoll_wait— block until one or more file descriptors are ready
Event loop flow
- Run an infinite loop:
- call
epoll_waitto learn which descriptors are ready - for ready descriptors: perform
read/write(or accept, process, respond) - if nothing is ready:
epoll_waitkeeps waiting, so the single thread doesn’t busy-wait
- call
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