askesis

Redis essentials: 50 cards on data types, caching and persistence

Redis basics: strings, lists, sets, sorted sets, hashes and streams, TTLs, RDB and AOF persistence, pub/sub, caching patterns, eviction and MULTI/EXEC.

DatabasesBeginner50 cardsFree

Practice now

Study without an account

0 of 50 seen0 graduated
What is Redis?

Scheduled with the default Askesis timings. Progress is saved in this browser.

All 50 cards

  1. 1
    What is Redis?
    An in-memory data structure server: keys map to strings, lists, sets, hashes, sorted sets, streams and more. Common uses are caching, sessions, queues, rate limits and leaderboards
  2. 2
    How does Redis execute commands?
    One at a time on a single main thread, so every command is atomic and never interleaves with another client’s command
    Redis 6+ can use I/O threads for networking, and some work, like freeing big values, runs in background threads.
  3. 3
    Why can one slow command hurt every client?
    Nothing else runs while the main thread is busy. Avoid KEYS *, SMEMBERS or HGETALL on huge keys, and long Lua scripts, in production
  4. 4
    KEYS vs SCAN
    KEYS returns every match in one blocking O(N) call; SCAN walks the keyspace in small steps with a cursor. Repeat with the returned cursor until it is 0; keys may appear more than once
    redis
    SCAN 0 MATCH user:* COUNT 100
  5. 5
    DEL vs UNLINK
    Both remove keys. DEL frees the memory right away (by default), which is slow for huge values; UNLINK removes the key at once and frees memory in a background thread
  6. 6
    What can a Redis string hold?
    Any binary-safe value up to 512 MB: text, numbers, serialized JSON or raw bytes; SET and GET are O(1)
  7. 7
    What do the two INCR calls return?
    redis
    SET views 10
    INCR views
    INCR missing
    11 and 1: INCR is atomic and treats a missing key as 0. It errors if the value isn’t an integer
  8. 8
    What does SET lock:job:42 worker-1 NX EX 30 do?
    Sets the key only if it doesn’t exist (NX), expiring after 30 seconds (EX); it returns nil if the key already exists. The basis of a simple lock
  9. 9
    What is a Redis list?
    An ordered sequence of strings with O(1) push and pop at both ends: LPUSH, RPUSH, LPOP, RPOP
  10. 10
    What does LRANGE mylist 0 -1 return?
    Every element of the list: negative indexes count from the end, so -1 is the last element
  11. 11
    Build a simple job queue with a list
    Producers LPUSH jobs …; workers call BRPOP jobs 0, which blocks until an item arrives (a timeout of 0 waits forever)
    A popped job is lost if the worker crashes; streams with consumer groups, or LMOVE to a processing list, add reliability.
  12. 12
    Keep only the 100 most recent items in a list
    redis
    LPUSH recent:42 "item"
    LTRIM recent:42 0 99
  13. 13
    What is a Redis set?
    An unordered collection of unique strings: SADD, SREM and SISMEMBER are O(1), and SINTER, SUNION and SDIFF combine sets
  14. 14
    What is a sorted set?
    Unique members, each with a floating-point score, kept ordered by score (ties ordered lexicographically); adding and ranking are O(log N)
    Typical uses: leaderboards, priority queues and time-based indexes.
  15. 15
    Build a leaderboard and read the top 10
    redis
    ZADD scores 1500 alice 1200 bob
    ZINCRBY scores 50 bob
    ZRANGE scores 0 9 REV WITHSCORES
    REV needs Redis 6.2+; older code uses ZREVRANGE.
  16. 16
    Store and update a user object in a hash
    redis
    HSET user:42 name Ada email [email protected]
    HGET user:42 name
    HINCRBY user:42 logins 1
    HGETALL returns every field; HSET takes several field–value pairs (HMSET is deprecated).
  17. 17
    Why use a hash instead of a JSON string?
    You can read or change one field (HGET, HINCRBY) without fetching and rewriting the whole object
    Since Redis 7.4, individual hash fields can even expire (HEXPIRE).
  18. 18
    What is a Redis stream?
    An append-only log of entries, each with an ID and field–value pairs; consumers read ranges, block for new entries, or share work through consumer groups
  19. 19
    What does XADD orders * id 42 total 9.99 do?
    Appends an entry to the orders stream; * makes Redis generate an ID like 1718000000000-0 (milliseconds, then a sequence number)
  20. 20
    How do stream consumer groups work?
    Each entry goes to one consumer in the group and stays pending until acknowledged with XACK, so messages from a crashed consumer can be claimed and retried (XAUTOCLAIM)
    redis
    XGROUP CREATE orders workers $ MKSTREAM
    XREADGROUP GROUP workers w1 COUNT 10 STREAMS orders >
    XACK orders workers 1718000000000-0
  21. 21
    Streams vs pub/sub
    Streams store messages, so consumers can replay history, acknowledge work and catch up after downtime; pub/sub delivers only to clients connected at that moment
  22. 22
    What is a HyperLogLog for?
    Counting unique items approximately (PFADD, PFCOUNT) with about 0.81% standard error, using at most 12 KB per key
    Example: unique visitors per day without storing every visitor ID.
  23. 23
    Give a key a time to live
    redis
    EXPIRE session:abc 1800
    SET session:abc "data" EX 1800
    The first adds a 30-minute TTL to an existing key; the second sets the value and TTL together. PEXPIRE takes milliseconds, EXPIREAT a Unix timestamp, and PERSIST removes the expiry.
  24. 24
    What do -1 and -2 from TTL mean?
    -1: the key exists but has no expiry. -2: the key doesn’t exist. Otherwise TTL returns the remaining seconds
  25. 25
    Does overwriting a key with SET keep its TTL?
    No. SET clears the expiry unless you add KEEPTTL (Redis 6.0+); commands that modify the value in place, like INCR, LPUSH or HSET, keep it
  26. 26
    How do expired keys get removed?
    Passively, when a client accesses an expired key, and actively, by a background cycle that samples keys with a TTL; expired keys can linger in memory briefly
  27. 27
    What is RDB persistence?
    Point-in-time snapshots of the dataset written to a compact file on a schedule or with BGSAVE; restarts are fast, but writes since the last snapshot are lost on a crash
  28. 28
    What is AOF persistence?
    An append-only file logging every write, replayed on restart. With the default appendfsync everysec you lose at most about a second of writes; always is safest and slowest
  29. 29
    Why does Redis rewrite the AOF?
    The log keeps growing with every write; a rewrite (automatic, or BGREWRITEAOF) replaces it with the minimal set of commands that recreates the current data
  30. 30
    With both RDB and AOF enabled, which one loads on restart?
    The AOF, because it is usually the more complete record of recent writes
    Using both is common: AOF for durability, RDB files for backups.
  31. 31
    Why can BGSAVE need a lot of extra memory?
    It forks a child that shares memory copy-on-write; every page the parent modifies during the save gets copied, up to double the memory under heavy writes
  32. 32
    Publish and subscribe to messages
    redis
    SUBSCRIBE news
    PSUBSCRIBE news.*
    PUBLISH news "hello"
    PSUBSCRIBE matches channels by pattern; PUBLISH returns how many subscribers received the message.
  33. 33
    What delivery guarantee does pub/sub give?
    At most once: messages aren’t stored, so a subscriber that is disconnected or slow to reconnect simply misses them
  34. 34
    Why does a subscribed connection reject GET?
    With the RESP2 protocol, a connection in subscribe mode can only run (un)subscribe commands, PING, RESET and QUIT; use a separate connection for other commands
    RESP3 connections can mix both.
  35. 35
    How does the cache-aside pattern work?
    Read from the cache; on a miss, load from the database and store it with a TTL. On writes, update the database and delete the cache key
    js
    // node-redis
    let user = await redis.get(`user:${id}`)
    if (!user) {
      user = JSON.stringify(await db.users.find(id))
      await redis.set(`user:${id}`, user, { EX: 300 })
    }
  36. 36
    On a write, why delete the cached value instead of updating it?
    Two concurrent writers can update the cache in the opposite order from the database, leaving stale data; deleting lets the next read load the fresh value
  37. 37
    Write-through vs write-behind caching
    Write-through writes to the cache and the database together on every write; write-behind writes to the cache and persists to the database later, which is faster but can lose data
  38. 38
    What is a cache stampede?
    A popular key expires and many requests miss at once, all hitting the database. Fix it with a lock so one request rebuilds the value, early refresh, or random TTL jitter
  39. 39
    Conventional Redis key naming
    Colon-separated namespaces from general to specific, like user:42:profile or session:abc123
  40. 40
    What is the default maxmemory-policy?
    noeviction: once maxmemory is reached, commands that add data fail with an out-of-memory error while reads keep working
    For a pure cache, switch to an eviction policy like allkeys-lru or allkeys-lfu.
  41. 41
    allkeys-lru vs volatile-lru
    allkeys-lru can evict any key; volatile-lru only evicts keys that have a TTL, and acts like noeviction if none do
  42. 42
    LRU vs LFU eviction
    LRU evicts the least recently used keys; LFU (Redis 4.0+) evicts the least frequently used, which better protects keys that are steadily popular
  43. 43
    Is Redis’s LRU eviction exact?
    No. It samples a few keys (maxmemory-samples, default 5) and evicts the best candidate among them, which approximates LRU cheaply
  44. 44
    What do MULTI and EXEC do?
    Commands after MULTI are queued; EXEC runs them in order as one block, with no other client’s command in between
    redis
    MULTI
    INCR orders:count
    LPUSH orders:recent 42
    EXEC
  45. 45
    Does a Redis transaction roll back if a command fails?
    No. If a command fails while running (say, a wrong type), the rest still execute. Only errors detected while queuing, like bad syntax, abort the whole transaction
  46. 46
    What does WATCH add to a transaction?
    Optimistic locking: if a watched key changes before EXEC, the transaction is aborted and EXEC returns nil, so the client retries
    redis
    WATCH balance:42
    GET balance:42
    MULTI
    SET balance:42 90
    EXEC
  47. 47
    Why use a Lua script (EVAL) instead of MULTI?
    A script runs atomically on the server and can branch on values it reads, like deleting a lock only if you still own it, which MULTI can’t express
    redis
    EVAL "if redis.call('GET', KEYS[1]) == ARGV[1] then return redis.call('DEL', KEYS[1]) end return 0" 1 lock:job:42 worker-1
  48. 48
    Pipelining vs transactions
    Pipelining sends many commands without waiting for each reply, saving round trips, but other clients’ commands can interleave; MULTI/EXEC is atomic
  49. 49
    How does Redis Cluster split data, and what breaks?
    Keys are spread over 16,384 hash slots across nodes; multi-key commands fail unless all keys are in the same slot
    Hash tags force a slot: {user:42}:cart and {user:42}:profile hash only user:42.
  50. 50
    Allow 100 requests per minute per IP
    redis
    INCR rate:203.0.113.7:202610151230
    EXPIRE rate:203.0.113.7:202610151230 60 NX
    Reject when INCR returns more than 100. EXPIRE … NX (Redis 7.0+) sets the expiry only on the first hit of the window.

Frequently asked questions

Does this deck apply to Valkey?

Yes. Valkey is a fork of Redis 7.2.4, so the commands and concepts here work the same; only features added to Redis later, like hash field expiry in 7.4, may differ.

Is Redis open source?

Redis moved to source-available licenses with version 7.4 in 2024, and Redis 8 added the AGPLv3 as an open-source option. Valkey remains BSD-licensed.

Can Redis be my primary database?

It can for data that fits in memory, with AOF persistence and replication, but most teams use it next to a database as a cache, queue or session store.