Redis
Backend
Database
Performance
Caching
Ask anything about this article
Hi! I've read this article.
What would you like to know?
@farhan
Redis isn't just a cache — it's a Swiss Army knife for backend development. Here's how to use every blade.
typescriptasync function getUser(userId: string): Promise<User> {
// 1. Check cache first
const cached = await redis.get(`user:${userId}`);
if (cached) return JSON.parse(cached);
// 2. Cache miss — query database
const user = await db.users.findById(userId);
// 3. Store in cache with TTL
await redis.setex(`user:${userId}`, 3600, JSON.stringify(user));
return user;
}
typescriptasync function updateUser(userId: string, data: Partial<User>) {
// Update database AND cache together
const user = await db.users.update(userId, data);
await redis.setex(`user:${userId}`, 3600, JSON.stringify(user));
return user;
}
typescript// Store session in Redis (replaces file/memory sessions)
app.use(session({
store: new RedisStore({ client: redis }),
secret: process.env.SESSION_SECRET,
resave: false,
saveUninitialized: false,
cookie: {
maxAge: 86400000, // 24 hours
httpOnly: true,
secure: true
}
}));
typescriptasync function rateLimit(ip: string, limit: number, window: number): Promise<boolean> {
const key = `rate:${ip}`;
const current = await redis.incr(key);
if (current === 1) {
await redis.expire(key, window);
}
return current <= limit;
}
// Usage: 100 requests per 60 seconds
if (!(await rateLimit(req.ip, 100, 60))) {
return res.status(429).json({ error: 'Too many requests' });
}
typescriptimport { Queue, Worker } from 'bullmq';
// Producer
const emailQueue = new Queue('emails', { connection: redis });
await emailQueue.add('welcome', {
to: 'user@example.com',
subject: 'Welcome!',
template: 'welcome'
});
// Consumer
const worker = new Worker('emails', async (job) => {
await sendEmail(job.data);
console.log(`Sent ${job.data.subject} to ${job.data.to}`);
}, { connection: redis });
typescript// Publisher
await redis.publish('notifications', JSON.stringify({
userId: '123',
message: 'New order received!',
type: 'order'
}));
// Subscriber
const subscriber = redis.duplicate();
await subscriber.subscribe('notifications');
subscriber.on('message', (channel, message) => {
const data = JSON.parse(message);
// Push to WebSocket client
wsClients.get(data.userId)?.send(message);
});
typescript// Add scores
await redis.zadd('leaderboard', 2500, 'player:alice');
await redis.zadd('leaderboard', 3200, 'player:bob');
await redis.zadd('leaderboard', 1800, 'player:charlie');
// Get top 10
const top10 = await redis.zrevrange('leaderboard', 0, 9, 'WITHSCORES');
// ["player:bob", "3200", "player:alice", "2500", ...]
// Get player's rank
const rank = await redis.zrevrank('leaderboard', 'player:alice');
// 1 (0-indexed, so 2nd place)
| Tip | Why |
|---|---|
| Set TTL on everything | Prevent memory leaks |
| Use key namespacing | %%INLINECODE_0%% pattern |
| Enable persistence (RDB + AOF) | Survive restarts |
| Use Redis Cluster for >25GB | Horizontal scaling |
| Monitor with Redis Insight | Visual debugging |
| Use connection pooling | Avoid connection overhead |
Redis is the backbone of fast, scalable applications. Master it and your backend will fly.