Lesson 1 said Redis’s superpower is that it stores data structures, not opaque blobs. This lesson is those structures — the six core types, what each does, and the jobs each is perfect for. The practical skill is matching the structure to the problem: when a problem maps onto a Redis structure, the solution collapses from a batch job into a handful of fast commands.
The six core structures
- String — the simplest type: a value that can be text, a number, raw bytes, or a serialized object (JSON).
GET/SETto read and write;INCR/DECRto use it as an atomic counter (page views, rate-limit counts);SET ... EXto add a TTL. MeasuredINCRat 105,988 ops/sec. Use for: cached values, counters, flags, serialized sessions. - List — an ordered sequence of strings, with push/pop at both ends (
LPUSH/RPUSH/LPOP/RPOP). Acts as a queue (push one end, pop the other) or a stack, andLRANGEreads a slice. MeasuredRPUSHat 99,800 ops/sec. Use for: simple job queues, “recent N items,” activity timelines. - Hash — a map of fields→values under a single key, like a small object:
user:42 → {name, email, last_login}.HSET/HGET/HGETALL, and you can read or update a single field without rewriting the whole object. MeasuredHSETat 95,831 ops/sec. Use for: storing objects compactly, partial updates. - Set — an unordered collection of unique members:
SADDadds, duplicates are ignored,SISMEMBERtests membership. The power is set operations:SINTER(intersection),SUNION(union),SDIFF(difference) — computed server-side. MeasuredSADDat 95,740 ops/sec. Use for: tags, unique visitors, “users who did X” and intersecting audiences, social-graph relationships. - Sorted Set (ZSet) — the most powerful structure: unique members, each with a numeric score, kept in sorted order.
ZADD member score, thenZRANGE/ZREVRANGEfor ranges,ZRANKfor a member’s position — all O(log n). MeasuredZADDat 106,326 ops/sec. Use for: leaderboards (score = points, read the top-N instantly), priority queues (score = priority), rate limiters (score = timestamp, sliding window), anything “ranked” or “ordered by a number.” - Stream — an append-only log of entries with ids, plus consumer groups for distributed, acknowledged consumption (full treatment in Lesson 6). Use for: durable queues and event streams where you can’t lose messages.
All of these run at ~100,000 operations per second on a single instance (measured), because they’re in RAM and the operations are O(1) or O(log n).
The skill: match structure to problem
The reason Redis feels magical when used well is that so many problems map directly onto one of these structures, and when they do, the solution is a few commands instead of a subsystem:
- A leaderboard is a sorted set.
ZADD leaderboard 4820 "player:7"to update a score;ZREVRANGE leaderboard 0 9 WITHSCORESfor the top 10;ZREVRANK leaderboard "player:7"for a player’s rank. Real-time rankings over millions of players — each operation O(log n). Doing this in a relational database means an expensive sorted query on every read; in Redis it’s instant. - A unique-visitor count is a set.
SADD visitors:2026-10-30 user:42;SCARDfor the count. (For huge cardinalities, HyperLogLog — Lesson 11 — does it in ~12 KB.) - A session store is a hash with a TTL.
HSET session:abc field value,EXPIRE session:abc 1800. - A rate limiter is a counter or a sorted set.
INCRa per-window key withEXPIRE, or a sliding window with a sorted set of timestamps (Lesson 11). - A recent-activity feed is a capped list.
LPUSH feed:user:42 item,LTRIM feed:user:42 0 99to keep the latest 100.
So the design question for any Redis task is: “which structure does this problem naturally fit?” Get that right and the implementation is trivial, atomic, and fast. Get it wrong (e.g. serializing a list into a string and re-parsing it on every access) and you lose the server-side operations that make Redis fast. Learn the structures and their operations well — they’re the vocabulary of everything else in this course, from caching to coordination to the advanced patterns. Next we look at the constraint all of this lives under: memory and expiry.
Pitfalls to Avoid
- Serializing a structure into a string. Storing a JSON array in a string and re-parsing it in your app on every access throws away Redis’s server-side operations. Use the native list/hash/set/sorted-set so Redis does the work.
- Using the wrong structure. A leaderboard on a plain list means sorting in the app; a “unique” collection on a list means dedup in the app. Match the structure (sorted set, set) to the access pattern.
- Ignoring O(n) commands on big structures. Some commands are O(n) (
LRANGE 0 -1on a huge list,SMEMBERSon a giant set). On the single thread, these block everything (Lesson 12). Read ranges/pages, or useSCAN-family cursors. - One giant key. A list or hash with millions of elements is a “big key” that’s slow to operate on and hard to evict (Lesson 12). Split it (e.g. per-day, per-shard) or cap it (
LTRIM). - Forgetting TTLs on structures. The same memory discipline (Lesson 3) applies to every structure — a sorted set or hash with no expiry grows forever. Cap or expire them.
Quick Recap
- Six core structures (each ~100k ops/sec, measured): String (value/counter —
GET/SET/INCR), List (ordered — queue/stack), Hash (object of fields), Set (unique members + set ops), Sorted Set (scored & ordered —ZADD/ZRANGE, O(log n)), Stream (append-only log + consumer groups). - Sorted sets are the most powerful: leaderboards, priority queues, sliding-window rate limits — anything ranked by a number, in O(log n).
- The skill is matching structure to problem: a leaderboard is a sorted set, a unique-count is a set — then the solution is a few atomic commands, not a job.
- Use the native structures (not serialized blobs) so Redis does the work server-side; beware O(n) commands and big keys (Lesson 12).
Next lesson: the constraint everything lives under — keys, expiry and memory (TTLs, maxmemory, eviction).