Most people meet Redis as "a cache," but that undersells it. Redis is an in-memory data structure store: a server that holds rich data types — strings, hashes, lists, sets, sorted sets, streams — in RAM and exposes atomic operations on them over the network. That combination of data structures plus microsecond latency is why Redis ends up behind caching, session stores, rate limiters, leaderboards, queues, and pub/sub, often all in the same system. This is the technology our caching and leaderboard articles keep reaching for; here's how it actually works.

⚡ Quick Takeaways
  • Not just a cache — a data structure server. Strings, hashes, lists, sets, sorted sets, streams, bitmaps, HyperLogLog, and geo, each with atomic O(1)/O(log n) operations.
  • In-memory + single-threaded for command execution — RAM speed plus no locks means simple, predictable, extremely fast operations (~100K+ ops/sec per node).
  • Persistence is optional and tunable — RDB snapshots (compact, fast restart, can lose recent writes) vs AOF append-only log (more durable, larger); often both.
  • Eviction makes it a cache — set maxmemory and a policy (LRU/LFU/TTL) and Redis evicts under pressure.
  • HA via replication + Sentinel; scale via Cluster — Cluster shards the keyspace across 16,384 hash slots.
  • Watch big keys, hot keys, and blocking commands — one slow O(n) command stalls the single thread for everyone.
tldr

Redis keeps typed data structures in memory and runs commands on a single thread, so operations are atomic and blazing fast. Persist with RDB (snapshots) and/or AOF (write log) depending on how much data loss you can tolerate. Use eviction policies to run it as a cache, replication + Sentinel for high availability, and Cluster (hash slots) to scale horizontally. Its data types unlock far more than caching: leaderboards (sorted sets), rate limiting, queues, pub/sub, and locks.

Why In-Memory and Single-Threaded

Two design choices explain Redis's speed. First, it keeps data in RAM, so reads and writes avoid disk entirely — latencies are microseconds, not milliseconds. Second, command execution is single-threaded: one command runs at a time on one core, processed through an event loop. That sounds like a limitation, but it's a feature: there are no locks, no race conditions between commands, and every operation is naturally atomic. You never get a half-applied increment. The CPU is rarely the bottleneck for an in-memory store — the network and memory bandwidth are — so a single thread comfortably handles 100K+ operations per second. (Modern Redis does use threads for I/O and background tasks, but the core command execution remains single-threaded.)

key implication

Because one thread serves everyone, a single slow command blocks all other clients. Running KEYS * or a big SMEMBERS on a million-element set freezes the server for the duration. The cardinal rule of operating Redis is: keep individual commands fast and avoid O(n) operations on large structures on the hot path.

The Data Structures

What sets Redis apart from a plain key-value cache like Memcached is its typed values with operations that run server-side:

data structures, server-side and atomic
SET   session:42 "..."  EX 3600     # string + 1h TTL
INCR  views:home                    # atomic counter
HSET  user:42 name "Ada" tier gold  # object as a hash
ZADD  board 9820 alice              # sorted set → leaderboard
ZREVRANK board alice                # O(log n) rank
LPUSH jobs "task1"  /  BRPOP jobs 0  # simple queue

Persistence: RDB vs AOF

In-memory doesn't have to mean ephemeral. Redis offers two persistence mechanisms so it can survive restarts:

AspectRDB (snapshot)AOF (append-only file)
What it storesPoint-in-time dump of the datasetEvery write command, replayed on start
DurabilityCan lose writes since last snapshotUp to ~1s loss (fsync everysec)
File size / restartCompact; fast restartLarger; slower replay
CostPeriodic fork can spike memoryContinuous write + rewrite/compaction

RDB is great for backups and fast restarts; AOF is better when you can't afford to lose more than a second of writes. The common production setup runs both — AOF for durability, RDB for quick backups — and many use a hybrid format. If you're using Redis purely as a cache, you might disable persistence entirely and treat data as recomputable.

Eviction and Expiration

To use Redis as a cache, you cap its memory with maxmemory and pick an eviction policy for when it's full: allkeys-lru (evict least-recently-used), allkeys-lfu (least-frequently-used — better for skewed access), volatile-ttl (evict soonest-to-expire among keys with a TTL), or noeviction (reject writes). Separately, keys can carry a TTL via EXPIRE. Redis expires keys both lazily (on access) and actively (a background sampler removes expired keys), balancing CPU against memory. Eviction (note: Redis approximates LRU/LFU by sampling, not a perfect global ordering) is what lets it serve as the cache layer described in our caching deep dive.

Replication and High Availability

A single Redis node is a single point of failure. Replication adds one or more replicas that asynchronously copy the primary's data — useful for read scaling and as warm standbys. For automatic failover, Redis Sentinel monitors the primary and replicas; if the primary goes down, Sentinel reaches a quorum, promotes a replica, and reconfigures clients. Because replication is asynchronous, a failover can lose the last few writes that hadn't reached the promoted replica — the same durability-vs-availability tradeoff seen across distributed systems (see our DDIA notes on replication).

Redis Cluster: Horizontal Scaling

When the dataset or write throughput outgrows one node, Redis Cluster shards the keyspace across multiple primaries. It divides the key space into 16,384 hash slots; each key maps to a slot via CRC16(key) mod 16384, and each primary owns a range of slots. Adding a node means moving some slots to it — only the affected keys migrate, not the whole keyspace.

cluster: keys → 16,384 hash slots → nodes
slot(key) = CRC16(key) mod 16384

  node A: slots     0 – 5460      (+ replica)
  node B: slots  5461 – 10922     (+ replica)
  node C: slots 10923 – 16383     (+ replica)

  multi-key ops must share a slot → use a {hashtag}:
     MGET {cart:42}:items {cart:42}:total   # both hash on "cart:42"

The catch: multi-key operations (and transactions) only work if all keys live in the same slot, which you force with a hash tag — the part in {} is what's hashed. This is the main thing that makes app code Cluster-aware.

What Redis Is Actually Used For

The data structures map directly onto a surprising range of jobs:

Redis vs Memcached

AspectRedisMemcached
Data typesRich (lists, sets, ZSETs, streams…)Strings/blobs only
PersistenceRDB + AOFNone (pure cache)
Replication / HAYes (replicas, Sentinel, Cluster)No built-in replication
ThreadingSingle-threaded coreMulti-threaded
Best forVersatile data structures, durabilitySimple, large multi-core key-value cache

Pitfalls

takeaway

Redis is best understood as a single-threaded, in-memory data-structure server — that framing explains its speed (RAM + no locks + atomic ops), its main risk (one slow command blocks everyone), and its versatility (the right data type turns Redis into a cache, queue, leaderboard, or lock). Reach for RDB/AOF when you need durability, Sentinel for failover, and Cluster (hash slots) when one node isn't enough.

🎯 interview hot-takes

Why is single-threaded Redis fast? Data is in RAM and one command runs at a time, so operations are atomic and lock-free; network/memory, not CPU, is the bottleneck.
RDB vs AOF? RDB = compact point-in-time snapshots, fast restart, can lose recent writes; AOF = append every write, ~1s durability, larger and slower to replay. Often run both.
How does Redis Cluster shard? 16,384 hash slots; key→slot via CRC16 mod 16384; each primary owns a slot range. Multi-key ops need a shared slot via a {hash tag}.
Redis vs Memcached? Redis has rich data types, persistence, and replication; Memcached is a simpler multi-threaded blob cache. Pick Redis unless you only need a plain cache.
Biggest operational risk? A slow O(n) command (KEYS, big collection reads) blocking the single thread for all clients.

← previous
GraphQL & REST Comparison