Redis & Memcached Deep Dive

0/4 in this phase0/45 across the roadmap

📖 Concept

Redis and Memcached are the top in-memory caching systems.

Redis vs Memcached

Feature Redis Memcached
Data structures Strings, Lists, Sets, Sorted Sets, Hashes, Streams Strings only
Persistence Optional (RDB/AOF) None
Replication Built-in primary-replica None
Pub/Sub Built-in None
Scripting Lua (atomic ops) None
Threading Single-threaded (I/O threads in 6.0+) Multi-threaded
Speed ~100K ops/sec ~100K ops/sec

When to Use Each

  • Redis: Need data structures, persistence, pub/sub, or multiple use cases
  • Memcached: Simple key-value caching with maximum memory efficiency

Redis Use Cases in System Design

Use Case Redis Feature
Caching GET/SET + TTL
Sessions Hash + TTL
Rate limiting Sorted Set
Leaderboards Sorted Set
Pub/Sub PUBLISH/SUBSCRIBE
Distributed locks SETNX + TTL
Counters INCR/DECR
Geospatial GEOADD/GEORADIUS

Pro tip: Say "Redis" in interviews. It's the industry standard.

💻 Code Example

codeTap to expand ⛶
1// ============================================
2// Redis Patterns for System Design
3// ============================================
4
5const Redis = require('ioredis');
6const redis = new Redis();
7
8// ---------- Distributed Lock ----------
9class RedisLock {
10 constructor(redis) { this.redis = redis; }
11
12 async acquire(lockName, ttlMs = 10000) {
13 const lockKey = `lock:\${lockName}`;
14 const lockValue = `\${Date.now()}:\${Math.random()}`;
15 const result = await this.redis.set(lockKey, lockValue, 'PX', ttlMs, 'NX');
16 return result === 'OK' ? { acquired: true, value: lockValue, key: lockKey } : { acquired: false };
17 }
18
19 async release(lockKey, lockValue) {
20 const lua = 'if redis.call("GET",KEYS[1])==ARGV[1] then return redis.call("DEL",KEYS[1]) else return 0 end';
21 await this.redis.eval(lua, 1, lockKey, lockValue);
22 }
23}
24
25// ---------- Leaderboard ----------
26async function leaderboard() {
27 await redis.zadd('leaderboard', 1500, 'alice', 2300, 'bob', 1800, 'carol');
28 const top10 = await redis.zrevrange('leaderboard', 0, 9, 'WITHSCORES');
29 const rank = await redis.zrevrank('leaderboard', 'alice');
30 await redis.zincrby('leaderboard', 100, 'alice');
31 console.log('Top 10:', top10, 'Alice rank:', rank + 1);
32}
33
34// ---------- Session Store ----------
35async function sessions() {
36 const sid = 'sess_abc';
37 await redis.hmset(`session:\${sid}`, { userId: '123', role: 'admin', loginAt: Date.now().toString() });
38 await redis.expire(`session:\${sid}`, 3600);
39 const role = await redis.hget(`session:\${sid}`, 'role');
40 console.log('Role:', role);
41}
42
43// ---------- Geospatial (Uber-like) ----------
44async function geo() {
45 await redis.geoadd('drivers', -122.4194, 37.7749, 'driver_1', -122.4089, 37.7835, 'driver_2');
46 const nearby = await redis.georadius('drivers', -122.4194, 37.7749, 5, 'km', 'WITHDIST', 'ASC', 'COUNT', 10);
47 console.log('Nearby drivers:', nearby);
48}
49
50leaderboard(); sessions(); geo();

🏋️ Practice Exercise

  1. Redis for Uber: Design Redis architecture for 5M driver locations updated every 4 seconds. What data structures?

  2. Redis vs DB: For each — sessions, product catalog, view counter, order history, rate limiting — choose Redis or PostgreSQL.

  3. Redis Cluster: Need 500GB cache, nodes max 64GB. Design cluster: masters, replicas, sharding, failover.

  4. Redis Persistence: Compare RDB snapshots vs AOF. When use each? When disable persistence?

⚠️ Common Mistakes

  • Using Redis without persistence when data must survive restarts — enable RDB or AOF.

  • Storing 5MB objects per key — wastes memory, increases latency. Break into smaller entries or use hashes.

  • Not setting maxmemory — Redis uses all RAM and gets OOM-killed. Always set limit + eviction policy.

  • Using Pub/Sub for reliable delivery — it's fire-and-forget; disconnected subscribers lose messages. Use Redis Streams or Kafka.

💼 Interview Questions

🎤 Mock Interview

Practice a live interview for Redis & Memcached Deep Dive