SysDesignPrep.com
Study guide 24 of 183

Redis data structures and patterns

The Redis building blocks that appear in system designs: strings and counters, hashes, lists, sets, sorted sets for leaderboards and delayed queues, HyperLogLog, geospatial indexes, streams and pub/sub, Lua scripts, persistence, clustering and pitfalls.

Reading is half of it. See this used in a real interview: walk through Design a Real-Time Leaderboard →

Redis appears in almost every system design diagram, usually as "cache". It is far more useful than that: an in-memory server of data structures that solves leaderboards, rate limiters, session stores, delayed queues, presence, geospatial lookups and counters with a few commands. Knowing which structure fits which problem, and where Redis is the wrong tool, makes those boxes in your design specific and credible.

The structures and what they solve

StructureKey commandsTypical uses
StringGET, SET with EX, INCR, SETNXcache entries, counters, simple locks, feature values
HashHSET, HGET, HINCRBYobjects with fields: sessions, user profiles, per-item stats
ListLPUSH, RPOP, LRANGE, LTRIMrecent items (capped timelines), simple queues
SetSADD, SISMEMBER, SINTERunique members, tags, "who liked this", mutual friends
Sorted setZADD, ZINCRBY, ZRANGE, ZRANGEBYSCORE, ZRANKleaderboards, priority and delayed queues, sliding-window logs, time-ordered feeds
HyperLogLogPFADD, PFCOUNT, PFMERGEapproximate unique counts in 12 KB
BitmapSETBIT, BITCOUNTdaily active flags per user id, feature membership
GeoGEOADD, GEOSEARCHnearby drivers or places (built on sorted sets with geohashes)
StreamXADD, XREADGROUP, XACKlightweight durable-ish event logs with consumer groups
Pub/subPUBLISH, SUBSCRIBEfire-and-forget fan-out to connected servers

Patterns

Cache-aside with TTL: GET; on a miss, read the database and SET key value EX 300. Add jitter to TTLs and request coalescing for hot keys. See caching.

Leaderboard: ZINCRBY board score user; top 10 with ZRANGE board 0 9 REV WITHSCORES; a user's rank with ZREVRANK. Logarithmic updates and ranks for millions of members. Shard by board or by score range for huge boards. See Design a Leaderboard.

Rate limiter: fixed window with INCR plus EXPIRE; sliding window log with a sorted set of timestamps (ZADD, ZREMRANGEBYSCORE, ZCARD); token bucket in a Lua script for atomicity. See Design a Rate Limiter.

Delayed queue: ZADD jobs due_time job_id; workers fetch due ones with ZRANGEBYSCORE jobs 0 now and claim them atomically. See delayed jobs and distributed cron.

Capped timeline: LPUSH timeline:user post_id then LTRIM timeline:user 0 799. See fan-out on write vs read.

Nearby search: GEOADD drivers lon lat driver_id, GEOSEARCH drivers FROMLONLAT lon lat BYRADIUS 2 km. Frequent location updates are cheap. See Design Uber.

Presence: SET online:user 1 EX 60, refreshed by heartbeats. See presence and connection management.

Distributed lock: SET lock value NX PX 10000 and release with a value-checking script; fine for efficiency, not for correctness. See distributed locks and leases.

Atomicity

Each command is atomic, because Redis executes commands on a single thread. For multi-step logic (check then update), use a Lua script or a function so it runs atomically, or MULTI/EXEC transactions with WATCH for optimistic checks. Keep scripts short: while one runs, everything else waits.

Durability

Redis is in memory first:

  • RDB snapshots periodically: compact, but lose writes since the last snapshot.
  • AOF (append-only file) logging every write, fsynced every second or every write: less loss, more I/O.
  • Replication is asynchronous: a failover can lose recent acknowledged writes.

So treat Redis as a cache or as a store where losing a second of data is acceptable, unless you use a variant designed for stronger durability. Keep the source of truth for money and orders in a database.

Scaling

  • Redis Cluster splits keys into 16,384 hash slots across primaries, each with replicas. Multi-key commands work only when keys share a slot; use hash tags ({user:42}:cart, {user:42}:profile) to co-locate related keys.
  • Read replicas for read-heavy data (with replication lag).
  • Memory is the limit: estimate key count times size, plus overhead. See back-of-envelope estimation.

Pitfalls

  • Big keys: a sorted set with 50 million members or a 100 MB string blocks the server during operations and slows migration. Split them.
  • Hot keys: one key on one shard takes all the traffic. Replicate or cache locally. See hot keys and skew.
  • Slow commands: KEYS *, large SMEMBERS or LRANGE 0 -1 block everyone; use SCAN and bounded ranges.
  • Eviction surprises: with a memory limit and an eviction policy, keys disappear; make sure that is acceptable for every key type stored there.
  • Pub/sub is not durable: disconnected subscribers miss messages. Use streams or a real broker when delivery matters.

Checklist

  • Pick the structure that matches the access pattern.
  • Lua scripts for multi-step atomic logic.
  • Persistence and failover behaviour understood; no money as the only copy.
  • Cluster hash tags for related keys; memory estimated.
  • No big keys, slow commands or unbounded ranges; hot keys mitigated.

Open in your browser to sign in

Google does not allow sign-in inside this app's built-in browser. Open this page in Safari and sign in there. The link opens this same page.

Tap the ⋯ or share button at the top or bottom of the screen, then Open in browser. Or copy the link and paste it into Safari.