Exercises
Six Redis exercises that come up in real systems. Pick the right data type and command, explain the trade-off. Answers below.
Six Redis design drills
EXAMPLE
# ============================================================
# Drill 1 — Last-seen for online presence
# ============================================================
# TASK: track 'last seen at' for 100k users; query 'is X online (seen in last 60s)'.
#
# ANSWER: SORTED SET keyed on user id, score = epoch ms.
# ZADD presence $now user_id
# Query active in last 60s: ZRANGEBYSCORE presence ($now - 60_000) +inf
# Garbage collect with: ZREMRANGEBYSCORE presence 0 ($now - 60_000)
# Why: O(log N) writes, O(log N + M) reads, automatic 'sorted by time'.
# Memory: ~50 MB at 100k users — well within budget.
# ============================================================
# Drill 2 — Cooldown timer per action
# ============================================================
# TASK: 'user can claim daily reward at most once per 24h'.
#
# ANSWER: SET ... NX EX
# SET cooldown:claim:42 1 NX EX 86400
# On nil response, reject (the lock was held).
# Why: atomic claim + TTL in one round trip.
# ============================================================
# Drill 3 — Top-N visited pages this minute
# ============================================================
# TASK: count page views per URL, return top 10 for the current minute.
#
# ANSWER: ZSET per minute bucket.
# ZINCRBY views:202606181232 1 /url
# ZREVRANGE views:202606181232 0 9 WITHSCORES
# EXPIRE views:202606181232 600 # keep only last 10 buckets
# Why: O(log N) increments, O(log N + 10) top read.
# ============================================================
# Drill 4 — Dedup messages across a moving 1-hour window
# ============================================================
# TASK: incoming webhook ids must be processed AT MOST ONCE per hour.
#
# ANSWER: SET ... NX EX
# SET dedupe:$id 1 NX EX 3600
# Treat non-OK reply as 'duplicate, skip'.
# ============================================================
# Drill 5 — Fan-out a notification to all subscribers
# ============================================================
# TASK: 100 subscribers want every 'order.shipped' event delivered.
#
# ANSWER: Streams + Consumer Groups.
# XADD orders.shipped * order_id 42 user_id 7
# XGROUP CREATE orders.shipped notify-svc $ MKSTREAM
# XREADGROUP GROUP notify-svc consumer-1 COUNT 16 BLOCK 5000 STREAMS orders.shipped >
# XACK orders.shipped notify-svc <id>
# Why: durable, supports retry via XPENDING. Pub/Sub has no replay.
# ============================================================
# Drill 6 — Job scheduler ('run after 5 minutes')
# ============================================================
# TASK: schedule jobs to run at future timestamps; consumer pulls due jobs.
#
# ANSWER: ZSET keyed by run_at score.
# ZADD jobs $runAt $jobId
# Consumer loop:
# ZRANGEBYSCORE jobs 0 $now LIMIT 0 16
# for each id: ZREM jobs id; process(id)
# Why: O(log N) writes, O(log N + M) reads of due items.
# ============================================================
# Scoring
# ============================================================
# 6 / 6 -> ready for production caches and queues
# 4 / 6 -> revisit redis/cheatsheet
# < 4 -> read https://redis.io/docs/data-types/
# ============================================================
# Pitfalls
# ============================================================
# - 'PUBSUB for job queues' -> no replay; consumers offline = events lost
# - 'KEYS *' to enumerate -> O(N) blocking; use SCAN
# - Storing 1MB JSON blobs in strings -> Redis is in-memory; budget bites
# - No maxmemory + eviction policy -> OOM kills the server
Why it matters
Almost every "should this be in Redis?" question is "should this be in memory with TTL?". If yes, Redis. If the answer must survive a Redis restart, persist alongside — Redis is a cache + coordination layer, not a database. Once the dataset stops fitting comfortably in RAM, you have outgrown it.
Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.
Discussion
Loading…