Redis Overview

Redis is an in-memory data structure server. The important design move is not "put data in Redis", it is choosing the data structure and command shape that matches the production job.

Mental model Redis is a fast command processor over named in-memory data structures. A client sends small commands over TCP. Redis runs the command against a key, returns a reply, optionally expires or evicts data later, and can persist snapshots or append-only command history for restart recovery.

Where Redis Fits

Redis usually sits beside the source-of-truth database, not instead of it. PostgreSQL owns relational truth and durable invariants. Redis owns fast access paths, shared counters, temporary coordination, fanout, and lightweight event buffers.

Latency tool

Use Redis when repeated reads, counters, or coordination checks must avoid a slower database round trip.

cachesessionrate limit

Data structure tool

Use Redis when the primitive itself is the feature: set membership, sorted ranking, list pop, stream append, or atomic increment.

setssorted setsstreams

Failure tradeoff

Redis buys speed by making memory, expiry, eviction, persistence, and replica lag part of the application design.

TTLevictionAOF/RDB

How A Command Works

Clients talk to Redis with RESP, the Redis Serialization Protocol. RESP is a request-response wire format where clients send commands as arrays of bulk strings, and Redis returns command-specific replies. Pipelining lets clients send multiple commands before waiting for each response, reducing round trips.

Redis command path Interactive diagram showing clients, sockets, the event loop, command execution, in-memory data, persistence, and replicas. clients network and event loop single command path durability RESP ready fd fetch key lookup AOF replica reply many clients fds sockets read/write selects ready event loop epoll/kqueue RESP parse single op execute atomic cmd RESP serialize dict keyspace typed values async replica disk AOF/RDB
How to read this diagram

Select a component or arrow

Boxes are Redis runtime parts. Arrows are movement of requests, key lookups, replies, persistence, or replication. Select any part to focus the related path.

1 Client command

INCR rl:user:42 travels over TCP as RESP.

2 Parse

Redis parses command name and arguments.

3 Execute

The command mutates or reads an in-memory key.

4 Bookkeeping

TTL, AOF, replication, and memory policy may be touched.

5 Reply

Common RESP replies include integers, strings, arrays, nulls, and errors. RESP3 adds more reply types.

RESP Command Anatomy

The command SET name aniket is sent as an array of three bulk strings: command name, key, and value.

*3\r\n
$3\r\n
SET\r\n
$4\r\n
name\r\n
$6\r\n
aniket\r\n

*3 means the outer object is an array of three items. Each $N line says the next bulk string has N bytes. The text form is enough here: RESP is intentionally simple.

Core Internals

Part What it does Why it matters
Keyspace Top-level namespace mapping string keys to typed values. The key name is the routing and lifecycle unit. TTL, deletion, and cluster placement all hang off keys.
Native data structures Strings, hashes, lists, sets, sorted sets, streams, and other types. Redis commands operate directly on structures, so the modeling choice decides both correctness and performance.
Atomic commands Single commands run as indivisible operations from the perspective of other clients. INCR, SET NX PX, HINCRBY, and XADD avoid client-side read-modify-write races.
Transactions MULTI queues commands and EXEC runs them as one isolated batch. WATCH adds optimistic check-and-set. Useful when commands must be grouped. Redis transactions are not SQL transactions: executed command errors do not roll the batch back.
Expiry Keys can have TTLs through commands such as EXPIRE, SET EX, and SET PX. Expiry turns Redis into a temporary truth layer: cache entries, rate windows, sessions, and leases can disappear by design.
Persistence RDB snapshots capture point-in-time state. AOF logs write operations with configurable fsync policy. Persistence reduces restart loss, but Redis is still usually designed as memory-first infrastructure.
Eviction maxmemory and maxmemory-policy decide what happens when Redis exceeds memory budget. A cache may safely evict. A lock, session, or queue may not be safe to evict without application consequences.
Replication and failover Redis can replicate writes to replicas and use Sentinel or Cluster patterns for availability and scaling. Replicas help reads and recovery, but asynchronous replication means recent writes can be lost during failover.

What Data Can Be Stored

Redis keys are strings. Values are typed data structures. A key cannot be both a string and a hash at the same time. A wrong command against the wrong type returns a type error.

Type Shape Good for Example commands
String Binary-safe bytes, integers as strings, JSON blobs, tokens. Cache values, counters, feature flags, idempotency markers, locks. GET, SET, INCR, MGET
Hash Field-value map under one key. Small objects such as session fields, user profile fragments, payment status fields. HSET, HGET, HINCRBY
List Insertion-ordered sequence. Simple queues, recent activity, bounded history. LPUSH, RPOP, BLPOP
Set Unordered unique members. Membership, deduplication, online users, permissions, tags. SADD, SISMEMBER, SINTER
Sorted set Unique members ordered by score. Leaderboards, delayed jobs, priority queues, time-window indexes. ZADD, ZRANGE, ZPOPMIN
Stream Append-only log with IDs and fields. Event buffers, consumer groups, persisted work delivery when Redis persistence, trimming, and failover settings match the requirement. XADD, XREAD, XGROUP, XACK
Bitmap Bit-level operations over a string. Daily active users, feature bitsets, compact boolean flags. SETBIT, GETBIT, BITCOUNT
HyperLogLog Probabilistic cardinality estimate. Approximate unique visitors or unique devices with tiny memory. PFADD, PFCOUNT
Geospatial Longitude and latitude indexed through sorted-set mechanics. Nearby stores, drivers, ATMs, or delivery zones. GEOADD, GEOSEARCH
JSON, time series, vector sets, search Structured document, metric, vector, and query features in current Redis distributions. Document caching, search indexes, metrics, vector similarity, AI retrieval paths. JSON.SET, FT.SEARCH, TS.ADD, VADD

Use Cases

The same Redis server can power many patterns, but each pattern has a different correctness story. Choose by asking: what is the source of truth, what can expire, what can be lost, and what must be atomic?

Cache-aside

Redis holds a copy of data whose durable home is somewhere else. Misses go to the database, then populate Redis with a TTL.

Risk: stale data, thundering herd on miss, and unsafe assumptions if Redis becomes the only copy.

GET product:42
SET product:42 "{\"stock\": 99}" EX 60
TTL product:42

Use Case Decision Rules

Use Redis for Good design Bad smell
Cache Database remains source of truth. Cache key has clear invalidation or TTL. Business-critical value exists only in Redis with eviction enabled.
Rate limiter Use atomic increments plus expiry. Keep window semantics explicit. Separate GET, app math, and SET under concurrency.
Lock or lease Use unique ownership token, SET NX PX, and token-checked release. Plain DEL lock without checking owner, or lock TTL longer than failure detection.
Queue Use streams and consumer groups when ack and retry matter. Using Pub/Sub for work that must survive subscriber disconnects.
Ranking Sorted set score is the ordering rule. Ties and updates are understood. Trying to run relational joins or arbitrary filtering inside Redis.
Dedup Set or string marker has a TTL aligned with replay window. Marker expires before upstream retries can arrive.

Hands-On Redis Labs

The lab pages explain the exact Redis commands, key shapes, Lua scripts, terminal output, and production gotchas behind each runnable experiment.

Cache stampede

Why many workers call the backend after the same key expires, and how a short fill lock reduces the herd.

Rate limiting

Fixed-window boundary bursts, sorted-set sliding windows, and why sliding windows are not fully smooth.

Locks

SET NX PX, ownership tokens, and Lua compare-and-delete for safe release.

Streams

Consumer groups, pending entries, crash recovery, XPENDING, and XAUTOCLAIM.

Pub/Sub

Fire-and-forget fan-out compared with stream-backed replay and acknowledgement.

Lua And Lua Scripts

Lua is a small embedded programming language. Redis embeds Lua 5.1 so clients can send scripts with EVAL or load them and call by hash. Scripts run on the Redis server, next to the data.

Why Lua matters Lua lets you compose several Redis commands into one atomic server-side operation. That avoids client round trips and prevents other clients from observing the middle of a multi-step update.
Lua script atomic execution Click components to see how a Lua script runs inside Redis as one atomic operation. Redis runs the whole script without interleaving another command client EVAL server-side Lua script one operation keyspace lock:payment read GET check token match DEL mismatch return 0 EVAL GET read if match mismatch reply
Atomic script

Lua runs beside the data

The client sends one script call. Redis executes the reads, checks, writes, and return value as one uninterrupted operation, so no other client sees the middle state.

When Lua is useful

Safe lock release script

EVAL "
if redis.call('GET', KEYS[1]) == ARGV[1] then
  return redis.call('DEL', KEYS[1])
else
  return 0
end
" 1 lock:payment:123 worker-a-uuid

This prevents one worker from deleting another worker's renewed or re-acquired lock. The key name is passed through KEYS. The owner token is passed through ARGV. That matters because Redis Cluster needs scripts to declare their key access clearly.

Fixed-window rate limiter script

EVAL "
local current = redis.call('INCR', KEYS[1])
if current == 1 then
  redis.call('EXPIRE', KEYS[1], ARGV[1])
end
return current
" 1 rl:user:42 60

The script makes the first increment and expiry setup one atomic operation. Without the script, a client crash between INCR and EXPIRE can leave a counter that never resets.

Lua cautions

Persistence, Eviction, And Durability

Redis can persist data, but persistence choice changes what failures mean.

Mechanism How it works Tradeoff
RDB snapshot Periodically writes a compact point-in-time snapshot. Fast restart file, but recent writes after the last snapshot can be lost.
AOF Appends write operations to a log and rewrites it in the background when needed. More durable with fsync policy, but larger files and possible write overhead.
No persistence Data lives only in memory. Fine for disposable cache, dangerous for source-of-truth state.
Eviction When maxmemory is exceeded, Redis follows the configured eviction policy. Safe for cache copies. Risky for locks, streams, sessions, and idempotency markers.

Redis Versus PostgreSQL

Question PostgreSQL answer Redis answer
What is the source of truth? Usually yes. Relational constraints, transactions, durable commits. Only when explicitly designed that way. Often a derived or temporary view.
How do I protect invariants? Transactions, row locks, constraints, isolation levels, atomic SQL. Atomic commands, Lua scripts, optimistic WATCH, careful key modeling.
What happens under memory pressure? Queries slow, disk and buffer behavior matter. Keys may be evicted or writes may fail, depending on policy.
What is the modeling unit? Tables, rows, indexes, constraints, joins. Keys and command-specific data structures.
What is the common mistake? Assuming read-modify-write is safe without the right lock or isolation. Assuming speed implies durability, or that TTL/eviction cannot affect correctness.

Practical First CLI Experiments

These are enough to learn the shape before writing application code.

# cache with TTL
SET product:42 "{\"price\": 1999}" EX 30
GET product:42
TTL product:42

# rate counter
INCR rl:user:42
EXPIRE rl:user:42 60
TTL rl:user:42

# lock acquisition
SET lock:payment:123 worker-a NX PX 5000
GET lock:payment:123

# stream event
XADD payments * id p1 amount 100
XREAD COUNT 1 STREAMS payments 0

# sorted ranking
ZADD leaderboard 900 user:42 850 user:7
ZREVRANGE leaderboard 0 9 WITHSCORES

Sources