Databases 19 min read

Why Is Redis So Fast? Inside Its Single‑Threaded and Multithreaded Architecture

This article explains how Redis achieves tens of thousands of QPS on average hardware, breaks down the technical reasons behind its speed—including C implementation, in‑memory design, epoll‑based I/O multiplexing, and a single‑threaded event loop—while also detailing the evolution to multithreaded I/O in later versions.

Architect
Architect
Architect
Why Is Redis So Fast? Inside Its Single‑Threaded and Multithreaded Architecture

Official benchmarks show that a single Redis instance on average Linux hardware can handle over 80,000 QPS for simple O(N) or O(log N) commands, and more than 1,000,000 QPS when using pipelined batch processing.

Why Redis Is So Fast

Implemented in C, which contributes to performance but is not the sole factor.

Pure in‑memory data store: no disk I/O, giving a natural speed advantage over disk‑based databases.

I/O multiplexing using epoll / select / kqueue enables high‑throughput network I/O.

Single‑threaded model avoids context‑switch and lock overhead, simplifying concurrency control.

Why a Single‑Threaded Model?

Redis’s CPU is rarely the bottleneck; most workloads are limited by memory bandwidth or network latency. Commands with O(N) or O(log N) complexity typically consume negligible CPU, so the event loop can serve many clients without CPU saturation.

The real performance limiter is network I/O, not CPU cycles. By keeping the core logic single‑threaded, Redis eliminates lock contention and context‑switch costs, while still achieving high throughput.

Is Redis Truly Single‑Threaded?

The answer depends on the scope. The core network model remained single‑threaded up to Redis 6.0, but multithreading was introduced for specific tasks (e.g., asynchronous deletion) starting with Redis 4.0. Redis v4.0 – added background threads for asynchronous commands such as UNLINK, FLUSHALL ASYNC, FLUSHDB ASYNC. Redis v6.0 – incorporated true I/O multithreading into the network stack.

Single‑Threaded Network Model (v1.0‑v5.x)

The model follows a classic Reactor pattern: a single event loop uses epoll / select / kqueue to monitor socket events, reads client requests, parses them, executes commands, and writes responses back.

Client structure : stores socket descriptor, selected DB pointer, read buffer ( querybuf), write buffer ( buf) and reply list ( reply). aeApiPoll: wraps the OS multiplexing call and returns ready events. acceptTcpHandler: accepts new connections and registers readQueryFromClient for each socket. readQueryFromClient: reads raw bytes into querybuf and triggers command parsing. processInputBufferprocessInlineBuffer / processMultibulkBufferprocessCommand: full command execution pipeline.

Response is placed into client->buf (16 KB fast buffer) or client->reply (linked list for large replies) and scheduled for write‑back via clients_pending_write.

Multithreaded Asynchronous Tasks (v4.0+)

To avoid blocking the main event loop on heavy commands (e.g., deleting a key with millions of elements), Redis offloads such operations to background threads. Commands like UNLINK, FLUSHALL ASYNC, and FLUSHDB ASYNC run asynchronously, improving throughput and availability.

Background threads execute the heavy work while the main thread continues handling other clients.

These tasks are non‑blocking and preserve high availability.

Multithreaded Network Model (v6.0+)

Redis 6.0 introduces a true multithreaded I/O model, often described as a Master‑Workers (or Main‑Reactor / Sub‑Reactor) architecture.

The main thread runs the primary event loop and registers acceptTcpHandler on the listening socket.

When a new client connects, the main thread accepts the connection and distributes the socket to one of several I/O worker threads.

Each I/O thread reads the request into client->querybuf and performs initial parsing.

Command execution (the actual processCommand call) still occurs in the main thread, ensuring data‑structure consistency.

After execution, the response is placed in the client’s write buffer and handed to an I/O thread for asynchronous write‑back.

Both read and write queues ( clients_pending_read, clients_pending_write) are balanced across workers using a round‑robin strategy.

Key Takeaways

Redis’s original single‑threaded reactor provides simplicity, low latency, and excellent cache‑like performance.

CPU is rarely the bottleneck; network and memory bandwidth dominate.

Multithreaded I/O introduced in v6.0 improves scalability for high‑concurrency workloads while preserving the single‑threaded command execution model.

Understanding these architectural choices helps developers tune Redis for maximum performance in real‑world deployments.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

performanceredisDatabase ArchitecturemultithreadingSingle‑threadedevent loop
Architect
Written by

Architect

Professional architect sharing high‑quality architecture insights. Topics include high‑availability, high‑performance, high‑stability architectures, big data, machine learning, Java, system and distributed architecture, AI, and practical large‑scale architecture case studies. Open to ideas‑driven architects who enjoy sharing and learning.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.