Redis High‑Level Design (HLD): How Redis Is Internally Built
Table of Contents
- Introduction: What You Will Learn
- Foundation (Beginner)
- What Redis Is and Why It Matters
- Core Concepts and Terminology
- System Context Diagram (Actors and Flows)
- Simple Mental Model: The Single‑Threaded Core
- Intermediate
- High‑Level Architecture Diagram
- Core Components and Responsibilities
- Data Flow and Interaction Diagrams
- Persistence: RDB and AOF
- Replication and High Availability
- Trade‑Offs Table
- Advanced
- Scaling with Redis Cluster
- Performance Optimizations and Edge Cases
- Consistency and Availability Choices
- Practical Application
- Worked Example: Building a Leaderboard
- Practice Problems with Solutions
- Implementation Tips and Gotchas
- Capacity Estimation Walkthrough
- Design Decisions and Rationale
- Summary and Next Learning Paths
1. Introduction: What You Will Learn
This guide explains Redis from a high‑level design perspective: how its internal system is created, how components fit together, and why specific design decisions were chosen. You will move from foundational concepts to advanced scaling, with diagrams, examples, and practical exercises. By the end, you should understand how Redis achieves fast performance, what trade‑offs it makes, and how to reason about Redis architectures in real systems.
2. Foundation (Beginner)
2.1 What Redis Is and Why It Matters
Redis is an in‑memory data store often used as a cache, a database, and a message broker. It is fast because most operations are served from RAM, and it uses efficient data structures. This matters for:
- Low latency (microseconds to single‑digit milliseconds).
- High throughput (hundreds of thousands of ops/sec on modest hardware).
- Versatility (strings, hashes, lists, sets, sorted sets, streams, etc.).
Real‑world use cases
- Session storage for web apps.
- Leaderboards and counters for games.
- Real‑time analytics and rate limiting.
- Pub/Sub messaging and streams.
2.2 Core Concepts and Terminology
- Key‑value store: Data is stored as key → value.
- In‑memory: Primary storage is RAM.
- Persistence: Optional disk durability (RDB snapshots, AOF logs).
- Replication: One primary (master) and multiple replicas (slaves).
- Cluster: Sharding data across multiple nodes.
- Sentinel: Monitoring and automated failover.
2.3 System Context Diagram (Actors and Flows)
+-----------+ +------------------+ +--------------+
| Client | RESP | Redis Server | Disk | Persistence |
| (App/API) +-------->+ (In-Memory DB) +------->+ (RDB/AOF) |
+-----------+ +------------------+ +--------------+
| |
| v
| +----------+
| | Replicas |
| +----------+
v
+-----------+
| Metrics |
+-----------+
Why this matters: Redis is not just a data structure library; it is a server that speaks a protocol (RESP), persists data, replicates, and participates in HA and cluster setups.
2.4 Simple Mental Model: The Single‑Threaded Core
Redis primarily uses a single event loop thread to handle commands. This avoids complex locking and makes performance predictable. Most operations are O(1) or O(log N).
Think of Redis as a fast cashier at a single register with a very efficient system: only one person serves customers, but the line moves quickly because each action is fast and predictable.
3. Intermediate
3.1 High‑Level Architecture Diagram
+-----------------------+
| Clients |
+-----------+-----------+
|
v
+-------------------------+
| TCP/RESP Interface |
+-----------+-------------+
|
v
+-------------------+ +--------------+ +------------------+
| Event Loop (Main) |-->| Command Exec |-->| Data Structures |
+-------------------+ +--------------+ +------------------+
| | |
| v v
| +-------------+ +-------------+
| | Memory | | Persistence |
| | Manager | | (RDB/AOF) |
| +-------------+ +-------------+
| |
v v
+--------------+ +--------------+
| Replication | | Pub/Sub |
+--------------+ +--------------+
3.2 Core Components and Responsibilities
- TCP/RESP Interface: Parses client commands and outputs responses.
- Event Loop: Multiplexes sockets and executes commands sequentially.
- Command Executor: Routes commands to the right implementation.
- Data Structures Layer: Strings, hashes, lists, sets, sorted sets, streams.
- Memory Manager: Eviction policies, expiration, memory accounting.
- Persistence Module: RDB snapshots and AOF logs.
- Replication: Ships writes from primary to replicas.
- Pub/Sub and Streams: Real‑time messaging and log‑like data.
3.3 Data Flow and Interaction Diagram
Example: SET user:1 "Alice" followed by GET user:1.
Client -> Redis: SET user:1 "Alice"
Redis: parse RESP
Redis: execute SET
Redis: update in-memory dict
Redis: append to AOF (if enabled)
Redis -> Client: OK
Client -> Redis: GET user:1
Redis: parse RESP
Redis: lookup key
Redis -> Client: "Alice"
3.4 Persistence: RDB and AOF
RDB (snapshot):
- Periodic snapshots of the dataset.
- Fast restart, compact file.
- Risk: data loss between snapshots.
AOF (append‑only file):
- Logs every write operation.
- Better durability.
- Larger file, periodic rewrite.
3.5 Replication and High Availability
Redis replication is asynchronous by default, which gives high write throughput but can risk data loss on failover. A primary streams writes to replicas.
+-----------+
| Primary |
+-----+-----+
|
Replication
|
+---------+---------+
| |
+--------+ +--------+
|Replica | |Replica |
+--------+ +--------+
For automated failover and monitoring, Sentinel coordinates elections and promotes a replica to primary if the primary fails.
3.6 Trade‑Offs Table
| Decision | Option A | Option B | Trade‑Off Summary |
|---|---|---|---|
| Persistence | RDB | AOF | RDB is faster and smaller; AOF is more durable but larger. |
| Consistency | Async replication | Sync replication | Async is faster but risks data loss; sync is safer but higher latency. |
| Scaling | Vertical | Horizontal (Cluster) | Vertical is simple but limited; Cluster scales but adds complexity. |
| Data model | Rich data structures | Plain key-value | Rich types reduce app logic but add memory overhead. |
4. Advanced
4.1 Scaling with Redis Cluster
Redis Cluster shards data across nodes using hash slots. Each key maps to a slot (0–16383), and slots are distributed across nodes.
+----------------+
| Client App |
+--------+-------+
|
v
+-----------------------+
| Cluster Proxy/SDK |
+----+-----------+------+
| |
v v
+---------+ +---------+
| Node A | | Node B |
| slots 0 | | slots 1 |
+----+----+ +----+----+
\ /
\ /
+-------+
| Node C|
| slots2|
+-------+
Why hash slots: Avoids keeping a giant mapping table and allows resharding with minimal movement.
4.2 Performance Optimizations and Edge Cases
- Pipeline commands to reduce round‑trip latency.
- Use appropriate data structures (e.g., sorted set for leaderboard).
- Memory policies (LRU/LFU, volatile vs allkeys).
- Avoid big keys (large values or huge collections) to prevent latency spikes.
- Background operations (AOF rewrite, RDB snapshot) can create I/O contention.
4.3 Consistency and Availability Choices
Redis favors availability and performance over strict consistency. During failover or network partitions, you can observe:
- Stale reads from replicas.
- Lost writes if the primary fails before replication completes.
This is a deliberate design choice to keep latency low and keep the system responsive under load.
5. Practical Application
5.1 Worked Example: Building a Leaderboard
Use a sorted set to store user scores.
ZADD leaderboard 100 "alice"
ZADD leaderboard 200 "bob"
ZADD leaderboard 150 "carol"
ZRANGE leaderboard 0 -1 WITHSCORES
Why this works: Sorted sets keep items ordered by score, making top‑N queries fast and reliable.
5.2 Practice Problems with Solutions
Problem 1: Design a rate limiter using Redis.
Solution (fixed window counter):
INCR rate:user:123
EXPIRE rate:user:123 60
Problem 2: Create a queue for background jobs.
Solution (list):
LPUSH jobs "job:1"
LPUSH jobs "job:2"
BRPOP jobs 0
Problem 3: Build a rolling window counter for analytics.
Solution (sorted set with timestamps):
ZADD events 1717210000 "evt1"
ZADD events 1717210030 "evt2"
ZREMRANGEBYSCORE events -inf 1717209940
ZCOUNT events 1717209940 1717210040
5.3 Implementation Tips and Gotchas
- Use EXPIRE for TTLs rather than manual cleanup.
- Avoid large single keys; prefer many small keys.
- Pipeline multiple reads/writes for better performance.
-
Monitor memory and set
maxmemorywith a policy. -
Beware blocking commands (like
BLPOP) in single‑threaded usage.
6. Capacity Estimation Walkthrough
Assume:
- 50k QPS peak.
- Average value size = 500 bytes.
- 100 million keys.
Memory estimate:
100,000,000 keys * 500 bytes = 50 GB raw data
Overhead (metadata + pointers) ~ 30% = 15 GB
Total ≈ 65 GB
Replication factor 2:
65 GB * 2 = 130 GB
Bandwidth estimate for writes:
20k writes/sec * 500 bytes ≈ 10 MB/s
7. Design Decisions and Rationale
- Single‑threaded command execution to avoid locking and ensure deterministic performance.
- In‑memory first to minimize latency for common operations.
- Optional persistence to let users trade speed for durability.
- Asynchronous replication to maximize write throughput.
- Hash‑slot sharding to scale horizontally with predictable routing.
8. Summary and Next Learning Paths
Redis is engineered around speed and simplicity: a single event loop, rich data structures, and optional durability. Its high‑level architecture prioritizes low latency and operational ease, while advanced features like clustering and sentinel provide scale and resilience.
Next learning paths:
- Deep dive into Redis data structures and time complexity.
- Explore Redis persistence tuning (AOF fsync strategies).
- Study Redis Cluster resharding and failover behavior.
- Compare Redis with other in‑memory systems like Memcached.
Top comments (0)