Databases Lesson 9: Redis Caching
Redis is an in-memory key-value store — lightning fast because it stores data in RAM. Used for caching, sessions, queues, and real-time data.
Core Data Structures
# Strings: simple key-value
SET user:1:name "Alice"
GET user:1:name # "Alice"
SETC user:1:token "abc123" 3600 # expire in 1 hour
# Lists: ordered, like arrays
LPUSH queue "job1" "job2" # push to left
RPOP queue # pop from right (FIFO)
# Sets: unique values
SADD online:users 1 2 3
SMEMBERS online:users
SISMEMBER online:users 1 # is user 1 online?
# Sorted Sets: set with scores (leaderboards!)
ZADD leaderboard 1500 "Alice"
ZADD leaderboard 2000 "Bob"
ZRANGE leaderboard 0 -1 WITHSCORES # sorted by score
# Hashes: object-like
HSET user:1 name "Alice" email "alice@x.com" age 30
HGET user:1 name
HGETALL user:1
Caching Pattern
const redis = require("redis");
const client = redis.createClient();
async function getUserById(id) {
// 1. Check cache
const cached = await client.get(`user:${id}`);
if (cached) return JSON.parse(cached);
// 2. Cache miss — fetch from database
const user = await db.query("SELECT * FROM users WHERE id = $1", [id]);
// 3. Store in cache (expire after 5 min)
await client.setEx(`user:${id}`, 300, JSON.stringify(user));
return user;
}
🏋️ Practice Task
Build a caching layer for your REST API. Cache GET /api/users/:id for 5 minutes. Invalidate cache when user is updated (DELETE key on PUT/PATCH). Track cache hits vs misses with Redis counters (INCR). Show hit rate stats at GET /api/stats.
💡 Hint: client.incr(“stats:cache:hits”) vs client.incr(“stats:cache:misses”). Ratio = hits/(hits+misses)