Redis Beyond the Cache: Data Structures, Persistence, and the Line It Won't Cross
Choosing Redis means accepting a specific failure boundary: asynchronous replication can lose recent writes, AOF's everysec policy can lose about a second, and Cluster is not strongly consistent. This article spells out those boundaries so teams know where Redis belongs and where they still need a database with stronger guarantees.
This guide lays out Redis as a memory-primary data structure server, not just a key-value cache. It explains the event-driven, non-blocking I/O model and why "single-threaded" is an oversimplification: core command execution is serialized, but background tasks like persistence and async deletion run on separate threads. The article then surveys the nine data types, from String and Sorted Set to Stream and HyperLogLog, showing how each maps to a concrete use case.
The middle sections draw the line between expiration and memory eviction, then compare RDB snapshots with AOF logs, including the loss windows each one tolerates. It walks through replication, Sentinel, and Cluster, clarifying that async replication can lose acknowledged writes and that Cluster is not strongly consistent. The final part covers classic failure patterns, cache penetration, breakdown, and avalanche, plus operational problems like big keys and hot keys, each with mitigation strategies. A decision tree at the end maps Redis's proper place: cacheable state, short-term state, or ephemeral messages, not authoritative data needing strict ACID.
Redis's guarantees are weaker than they first appear: AOF can lose a second, replication is asynchronous, and Cluster is not strongly consistent, so treating Redis as a durable store will surprise teams that assume database-like durability.
The distinction between expiration and eviction is a frequent source of configuration mistakes; using maxmemory eviction to manage data that cannot be rebuilt is effectively choosing silent data loss.
The article's threading nuance shows why performance claims like 'single-threaded' hide real complexity; serialized command execution avoids locks, but background work on other threads means the behavior is not a simple global lock.
Cluster's 16384-slot design forces application-level decisions about hash tags and multi-key operations, so jumping to Cluster for 'production' adds complexity that may not be justified when a single node plus Sentinel suffices.