DEV Community

Ricky512227
Ricky512227

Posted on

Redis Threading Model: Why “Single-Threaded” Is Misunderstood

TL;DR
Redis executes commands on a single main thread, but uses threads for networking, disk persistence, and memory cleanup.
This design makes Redis fast, predictable, and surprisingly scalable under high concurrency.


1. My Redis Confusion Story

About 5 years ago, while building my EventStreamMonitor project, I started using Redis for the first time.
Everyone kept saying, “Redis is single-threaded.”

But then I read about Redis 6.0 introducing I/O threading, and saw mentions of background threads.
I was confused. Was Redis really single-threaded, or was there more to the story?

So I dug in, ran experiments, and learned a lot. Here’s what I found.


2. What I Learned About Redis Threads

Redis has a main thread and supporting threads:

Single-threaded (the “heart” of Redis):

  • Command execution: SET, GET, INCR, etc.
  • Main event loop: Processes requests.
  • Data structure access: Reading and writing memory.

Multi-threaded (supporting cast):

  • Background I/O: Disk operations like writing AOF or closing files.
  • Lazy memory freeing: Cleans memory in the background (since 4.0).
  • Network I/O threads: Handle reading/writing to client sockets (since 6.0).
  • RDB snapshots: Forked processes create backups.

Think of it like a busy kitchen:
The chef (main thread) cooks each dish one at a time,
while assistants handle prep, clean-up, and serving. Everyone stays organized.

Redis Threading Model

Redis Threading Model


3. Mini Examples / Case Studies

Example 1: Single client, single command

Client A sends: SET x 10

Redis execution:
1. I/O thread reads the request
2. Main thread executes SET x = 10
3. I/O thread sends "OK" back

Outcome: x = 10 in memory
Enter fullscreen mode Exit fullscreen mode

Example 2: Multiple clients, sequential execution

Client A: SET x 10
Client B: INCR x
Client C: GET x

Execution order:
1. SET x=10 → x=10
2. INCR x → x=11
3. GET x → returns 11

Outcome: Commands are atomic and safe
Enter fullscreen mode Exit fullscreen mode

Example 3: Pipelining commands

Client sends 3 commands at once: SET a 1, SET b 2, SET c 3

Execution:
- Commands enter queue
- Main thread executes one by one: a=1, b=2, c=3
- I/O thread sends responses together: OK, OK, OK

Outcome: Feels simultaneous, but serial execution
Enter fullscreen mode Exit fullscreen mode

Example 4: Background tasks

Client: SET key "value"

Execution:
1. Main thread updates memory
2. Background thread may write to AOF for persistence
3. Main thread continues other commands

Outcome: Disk persistence does not block execution
Enter fullscreen mode Exit fullscreen mode

4. Common Misconceptions I Had

"Redis is completely single-threaded"
Only command execution is single-threaded. Background threads exist for disk and I/O.

"Redis can't use multiple CPU cores"
I/O threads can use multiple cores. Benchmarks show 37–112% throughput improvement with io-threads.

"Single-threaded means Redis is slow"
Actually faster due to no locks, better CPU cache usage, and no context switching.

"Race conditions can't happen"
Single commands are atomic, but sequences can interleave across clients.

"BLPOP blocks the server"
Only blocks the client connection, not the server.


5. Why Redis Keeps Command Execution Single-Threaded

Antirez, Redis creator, explained:

“A thread doing LPUSH would have to coordinate with other threads doing LPOP. Complexity outweighs the gains.”

Complex data structures (lists, sets, sorted sets, streams) would require locks.
Single-threaded execution ensures atomic operations and simpler, safer code.

Chef analogy again: The chef focuses on cooking dishes perfectly while assistants handle prep and cleanup.


6. How Redis Actually Performs

Even single-threaded, Redis is very fast:

Single-instance benchmarks:

  • Pipelining: 1.5M+ SET/sec, 1.8M+ GET/sec
  • Without pipelining: ~100k–140k QPS
  • Redis 8.0 with I/O threads: up to 7.4M QPS

Twitter production:

  • 105TB RAM, 39M QPS, 10k+ instances
  • Latency: <0.5ms
  • 100k+ open connections per instance

CPU is rarely the bottleneck; memory and network usually are.


7. Main Takeaway

  • Single-threaded execution is intentional, not a limitation
  • Eliminates many classes of bugs
  • Provides high throughput and predictability
  • Background threads handle support tasks without blocking the main execution
  • Understanding this helped me design better caching strategies for EventStreamMonitor

Redis reminds us: sometimes doing one thing at a time, really well beats trying to do everything at once.


8. Further Reading

Top comments (0)