Redis: Single-Threaded but Still Fast
Why Redis is single-threaded and still hits six-figure QPS.
~/posts/redis-single-thread $ cat post.md
The data structures
Redis stores values as String, List, Set, Sorted Set (ZSet),
or Hash. Aside from ZSet, every structure has O(1) insert,
lookup, and read; ZSet still has O(1) reads. That leaves Redis room
to optimize everything else.
The signature design decision is pure in-memory mode: without persistence, Redis is purely an in-memory cache, which trades away disk IO and lets the implementation focus on raw data-structure speed.
Throughput and the single thread
A single-connection Redis instance can sustain six-figure QPS. At that level the test machine isn’t the bottleneck — memory and CPU are faster than needed; the real bottleneck is network. Other hardware only starts to matter when you’re juggling many connections at once — e.g. ~60k QPS at 40k concurrent connections.
For most single-instance use cases this is plenty fast.
One thing Redis does to fight the network problem is its own in-process VM, used when memory is full. Unlike a typical database, Redis prefers pushing cold data to disk while keeping every key resident — this preserves a good “cold-data” cache hit rate. It also defines its own wire protocol, optimized for speed over generality, to skip a few syscalls. In short, CPU is rarely what’s bottlenecking Redis.
To be honest there isn’t a lot to say here — run a Redis yourself and you’ll see CPU never pegs while the network is already buffering requests. Adding threads here would barely help — CPU isn’t strained in the first place, and you’d pay locking overhead on top.
Multiplexed IO
This part is actually worth understanding. Multiplexed IO uses an event loop to watch many IO streams at once: Redis polls them all and handles ready streams in one pass, skipping wasted polling attempts. “Multi” refers to multiple network connections; “multiplexing” refers to sharing the single thread.
The effect is to compress the network-IO cost when handling many concurrent connections. If non-network hardware isn’t the limit, this is what gets the most out of the thing Redis spends most of its time on.
”Single-threaded” isn’t “only one thread”
Node.js is also single-threaded, but nobody runs a single Node process on a dual-core machine.
Same story with Redis. Even a single Redis instance internally offloads IO (network and disk) to threads it spawns. You can also configure a master-slave setup so heavy reads and searches go to a child. Even in a single-threaded application, you can manually balance across CPU cores via configuration — you know your app’s workload better than the OS scheduler does.