This episode dissects Redis internals: the single-threaded event loop with I/O multiplexing, multi-threaded I/O since Redis 6, as well as four persistence models — RDB snapshot, AOF log, a combination of both, and no-persistence mode as a pure cache.

In episode 1 you already knew what Redis is. Now it's time to dissect how it works inside. Episode 2 covers two architectural foundations: the single-threaded execution model that makes Redis so fast, and the persistence model that determines where data goes when the server dies.
These two things are often overlooked by beginners, yet they explain almost all the weird behavior of Redis in production — why latency sometimes spikes suddenly, why data is lost after a restart, and why one expensive command can stop everything. Let's begin.
The heart of Redis is a single-threaded event loop: all commands are executed by just one thread, sequentially. This sounds like a limitation, but it is actually the advantage — without conflicts between threads, Redis never pays the cost of locking and context switching.
client A ─┐
client B ─┼──> event loop (epoll / kqueue) ──> command execution
client C ─┘ │
└── one command at a timeHow does one thread serve thousands of connections at once? The answer is I/O multiplexing. Redis uses epoll on Linux and kqueue on BSD/macOS to monitor thousands of sockets at once and only processes sockets that are truly ready to send/receive data. This is efficient because the thread never waits blindly.
Redis's speed comes from the combination: data in RAM (no disk seeks), a lock-free event loop, and commands designed to be O(1) or O(log N). Because one command runs to completion without interruption, operations like INCR or SADD are naturally atomic — no transaction wrapper needed.
Since Redis 6, the network read/write process has been moved to separate threads. It's important to emphasize: command execution remains single-threaded; only moving data across the socket is done in parallel. This removes the network I/O bottleneck without sacrificing the simplicity of the execution model.
Info
The practical implication: one slow command like KEYS * will block the entire server. The discipline of using SCAN (episode 3) and SLOWLOG (episode 17) comes from understanding this model.
Redis data lives in RAM — when the process dies or the server restarts, everything is lost unless there's a persistence mechanism. Redis provides four models.
RDB is a point-in-time snapshot of the entire dataset, saved to a .rdb file periodically. Snapshots are created via a fork mechanism: the child process inherits the main process's memory and writes the snapshot without blocking the server.
redis-cli BGSAVEBGSAVE triggers a background snapshot. Its automatic configuration lives in redis.conf — for example save 900 1 means take a snapshot if there is at least 1 change within 900 seconds. RDB excels at fast restarts and backups, but it can lose the changes made since the last snapshot.
AOF records every write operation to a log file. When the server restarts, the AOF is replayed to rebuild the dataset — its durability is far higher than RDB because the granularity is per-operation.
redis-cli CONFIG GET appendonly
redis-cli INFO persistenceCONFIG GET appendonly shows whether AOF is enabled. INFO persistence gives complete details about RDB and AOF status. AOF can be configured with appendfsync always|everysec|no — everysec is the best balance between durability and performance.
The production recommendation is enabling both: RDB for fast restarts and point-in-time backups, AOF for per-operation durability. In Redis 7, the built-in AOF already uses a multi-part format that addresses the rewrite performance trade-off.
save 900 1
save 300 10
save 60 10000
appendonly yes
appendfsync everysecRead it line by line: the three save rules schedule RDB snapshots, appendonly yes enables AOF, and appendfsync everysec guarantees at most one second of data loss on crash. This configuration is the standard pattern for production Redis.
For a pure volatile cache, you can turn off all persistence: save "" and appendonly no. Data only lives in RAM and is lost on restart — perfect for caches whose data can be rebuilt from the primary database. The trade-off is clear: there is no recovery at all, so use it only for non-critical data.
All the decisions above can be verified and changed at runtime without a restart:
redis-cli CONFIG GET save
redis-cli CONFIG GET appendfsync
redis-cli CONFIG GET dirCONFIG GET save shows the active RDB snapshot rules, appendfsync shows the AOF policy, and dir shows the directory where .rdb and AOF files are stored. Changing via CONFIG SET takes effect immediately but is lost on restart — for a permanent change, write it to redis.conf as well.
| Model | Durability | Restart | Performance | Best For |
|---|---|---|---|---|
| RDB only | Low-medium | Fast | Good | Cache + periodic snapshots |
| AOF only | High | Slower | Slight overhead | Data needing quick recovery |
| RDB + AOF | Highest | Fast | Slight overhead | Production standard |
| None | No durability | Very fast | Best | Pure volatile cache |
There is no single answer. The persistence decision is a business decision: how many seconds of lost data are still acceptable, and how fast the restart must be.
Episode 2 dissected Redis internals: the single-threaded event loop with I/O multiplexing via epoll/kqueue, multi-threaded I/O since Redis 6 without changing the command execution model, as well as four persistence models — RDB snapshot, AOF log, a combination of both, and no-persistence mode.
Key takeaways:
epoll/kqueue lets one thread serve thousands of connections.appendonly yes + appendfsync everysec).In the next episode, episode 3, we start exploring data structures with Strings, Numbers & Key Management — Redis's most fundamental data type with SET/GET, atomic counter operations, safe key management with SCAN, and TTL management. Time to start typing!