MODULE 3/LESSON 1
🔴 Redis Architecture

Redis Data Structures Deep Dive

5 Redis data structures that replace entire feature systems — and why they're irreplaceable

14 min
Redis is not just a key-value cache. Its six core data structures each solve specific problems that would otherwise require separate systems. A sorted set eliminates the need for a ranking database. A pub/sub eliminates a message broker for simple notifications.

Key Concepts

Strings + INCR

Atomic counter operations. INCR, DECR, INCRBY are single-command, thread-safe. Builds rate limiters, view counters, unique ID generators without locking.

Hashes

Store objects as field-value maps. HGET/HSET individual fields without deserializing the whole object. User session: HSET user:1001 name 'Kyaw' role 'admin' lastSeen '2026-08-10'.

Sorted Sets (ZSET)

Every member has a numeric score. ZADD/ZRANGEBYSCORE/ZRANK provide O(log N) ranking. Leaderboards, priority queues, sliding window rate limiters.

Lists (Queues)

LPUSH/RPOP = queue. LPUSH/LPOP = stack. BLPOP = blocking queue (workers wait for jobs). Used in BullMQ for job queues.

Redis Architecture Patterns & Use Cases

Redis (In-Memory Store) Strings (INCR) Rate Limiter Hashes (HSET) Session Store Lists (LPUSH) Message Queue Sorted Sets (ZADD) Leaderboard

Memory Usage Efficiency (Hashes vs JSON Strings)

Storing 1,000,000 User Session Objects Approach 1: JSON Strings SET user:1001 '{"name":"Aung","role":"Admin"}' Memory Used: ~500 MB High overhead per key, JSON parsing required Approach 2: Hashes (HSET) HSET user:1001 name "Aung" role "Admin" Memory Used: ~100 MB Internal ziplist encoding, 5x memory savings

Redis Commands for Each Architecture Pattern

redis-commands.shbash
1# ── SESSION STORE ──
2HSET session:abc123 userId 1001 email user@example.com role admin
3EXPIRE session:abc123 3600  # Expire in 1 hour
4HGET session:abc123 userId  # → "1001"
5
6# ── RATE LIMITING (Fixed Window) ──
7INCR ratelimit:ip:192.168.1.1:2026-08-10-14  # Increment request count
8EXPIRE ratelimit:ip:192.168.1.1:2026-08-10-14 3600  # Reset in 1 hour
9GET ratelimit:ip:192.168.1.1:2026-08-10-14   # Check count
10
11# ── LEADERBOARD (Sorted Set) ──
12ZADD leaderboard 1500 "player:kyaw"    # Add/update score
13ZADD leaderboard 2300 "player:aung"
14ZREVRANK leaderboard "player:kyaw"     # → rank (0-indexed)
15ZREVRANGE leaderboard 0 9 WITHSCORES  # Top 10 players
16
17# ── DISTRIBUTED LOCK (Redlock) ──
18SET lock:order:ORD-9901 "worker-1" NX EX 10  # NX = only if not exists, EX = 10s TTL
19# → "OK" if lock acquired, nil if already locked
20
21# ── TASK QUEUE (List) ──
22LPUSH email:queue '{"to":"user@example.com","template":"order_confirmed"}'
23BRPOP email:queue 30  # Block and wait for up to 30s for a job

Redis Architecture Patterns

Use CaseData StructureKey PatternTTL Strategy
User SessionHashsession:{token}30 min rolling
JWT BlacklistSetblacklisted:tokensMatch token expiry
Rate LimiterString (INCR)ratelimit:{ip}:{window}Window duration
LeaderboardSorted Setleaderboard:{period}Daily/weekly reset
Distributed LockString (NX)lock:{resource}Short (5-30s)
Job QueueListqueue:{name}No TTL (persistent)
Pub/Sub Notif.Pub/Sub channels{event}:{entity}Real-time only
💡
Senior Architect Insight: Redis is single-threaded, which is why INCR is atomic without locks. All Redis commands execute sequentially, so complex operations like check-then-set must use Lua scripts or Redis Transactions (MULTI/EXEC) to stay atomic across multiple commands.