Redis in System Design: Data Structures and Use Cases

Redis explained for system design: strings, hashes, sorted sets and streams, caching, leaderboards, rate limits, persistence, replication and Redis Cluster.

Beginner 3 min read · Updated

Redis is an in-memory data store that serves reads and writes in well under a millisecond and offers rich data structures, not just key-value strings: hashes, lists, sets, sorted sets, streams and more. In system design it's the default choice for caching, but also for session storage, rate limiting, leaderboards, counters, distributed locks with care, and lightweight queues. Knowing which data structure fits each problem, and what happens when Redis restarts, is what interviewers look for.

App serverRedisin memoryCacheGET/SET with TTLLeaderboardsorted setRate limiterINCR + EXPIRERDB / AOFpersistence
One Redis, many jobs: the same in-memory store serves as a cache, a leaderboard and a rate limiter, with snapshots or an append-only file for durability.

Data structures and what they're for

StructureKey commandsTypical use
StringGET, SET key value EX 60, INCRCached values, counters, flags
HashHSET, HGET, HGETALLAn object's fields, such as a session or user profile
ListLPUSH, RPOP, LRANGERecent items, simple queues
SetSADD, SISMEMBER, SINTERUnique members, tags, "who's online"
Sorted setZADD, ZRANGE, ZREVRANK, ZRANGEBYSCORELeaderboards, priority queues, time-ordered indexes, sliding-window rate limits
StreamXADD, XREADGROUP, XACKAppend-only event logs with consumer groups
HyperLogLogPFADD, PFCOUNTApproximate unique counts with tiny memory. See probabilistic data structures
GeoGEOADD, GEOSEARCHNearby search within a radius. See geospatial indexing

Common patterns

  • Cache-aside: read Redis, fall back to the database on a miss and populate with a TTL. See cache strategies.
  • Leaderboard: ZINCRBY leaderboard 10 user:42 on each score; ZREVRANGE leaderboard 0 9 WITHSCORES for the top ten; ZREVRANK for a user's position. Every operation is logarithmic.
  • Rate limiting: INCR a per-user, per-minute key with an expiry for a fixed window, or a sorted set of timestamps for a sliding window. Use a Lua script so check-and-increment is atomic. See rate limiting.
  • Sessions: a hash per session with an expiry, shared by all app servers, so the app servers stay stateless. See scalability.
  • Counters: INCR is atomic, so millions of likes or views can be counted without races, flushed to the database periodically.
  • Pub/sub and streams: pub/sub for fire-and-forget fan-out (no persistence); streams when messages must be durable and acknowledged.

Redis runs commands one at a time on a single main thread, so each command is atomic. That's why INCR and Lua scripts need no locks, and also why one slow command (KEYS * on millions of keys) blocks everything. Use SCAN instead.

Persistence and durability

OptionHowData at risk on crash
NonePure cacheEverything (rebuilt from the source of truth)
RDB snapshotsPeriodic point-in-time dumpsChanges since the last snapshot (minutes)
AOF (append-only file)Log every write; fsync every second or alwaysAbout a second with everysec, or none with always (slower)
RDB + AOFBothSmall, with faster restarts

Treat Redis as a cache unless you've deliberately configured and tested durability. If losing its contents would lose business data, that data should also live in a durable database.

Memory and eviction

Everything lives in RAM, so set maxmemory and an eviction policy such as allkeys-lru for caches (evict the least recently used keys) or volatile-ttl to evict keys closest to expiry. Without a limit, memory grows until the process is killed. Use TTLs on cache keys, keep values small, and watch for big keys (a hash with millions of fields) that are slow to read and delete. See cache eviction.

Scaling and availability

  • Replication: a primary with replicas for read scaling and failover. Replication is asynchronous, so a failover can lose the last writes.
  • Sentinel or managed failover: monitors the primary and promotes a replica automatically.
  • Redis Cluster: shards keys across primaries using 16,384 hash slots; multi-key operations work only when keys share a slot, which you can force with hash tags such as {user42}:cart and {user42}:profile.
  • Hot keys: a single very popular key can overload one shard; replicate it or cache it in-process. See hot partitions.
  • Locks: Redis-based locks are fine for efficiency (avoid duplicate work) but need fencing tokens when correctness depends on them. See distributed locks.

Where it’s used

Caching and sessions

Hot database rows and user sessions served in under a millisecond, shared by stateless app servers.

Gaming and social

Sorted-set leaderboards and atomic counters for scores, likes and views.

API platforms

Per-key rate limiting with atomic Lua scripts across a fleet of gateways.

In an interview

  • Pick the right data structure: sorted sets for leaderboards, hashes for objects, INCR for counters.
  • Explain single-threaded atomicity and why slow commands are dangerous.
  • State the persistence setting and what's lost on a crash.
  • Cover maxmemory with eviction, replication and Redis Cluster hash slots.

Further reading