Free official course covering Redis data structures with Node.js examples. Best structured Redis learning available. Read →
Redis is an in-memory data store — a supercharged shared Map that your entire application cluster can access. It reads/writes in microseconds, supports TTL-based expiration, and persists to disk. The universal tool for: caching, sessions, rate limiting, real-time features, and lightweight queues.
Redis is like a Map that lives outside your process, survives restarts (with persistence), is shared across all server instances, and has built-in TTL for every key.
| Type | Use case | Key commands |
|---|---|---|
| String | Cache values, counters | SET, GET, SETEX, INCR |
| Hash | Objects with multiple fields | HSET, HGET, HMGET, HGETALL |
| List | Queues, recent activity | LPUSH, RPUSH, LRANGE, BRPOP |
| Set | Unique members, tags | SADD, SISMEMBER, SMEMBERS |
| Sorted Set | Leaderboards, rate limiting | ZADD, ZRANGE, ZSCORE |
npm install ioredis
import Redis from 'ioredis';
const redis = new Redis(process.env.REDIS_URL); // redis://redis:6379
// Cache-aside pattern
async function getUserById(userId) {
const key = `user:${userId}`;
const cached = await redis.get(key);
if (cached) return JSON.parse(cached);
const user = await db.users.findById(userId);
await redis.setex(key, 300, JSON.stringify(user)); // 5 min TTL
return user;
}
// Invalidate on update
async function updateUser(userId, data) {
await db.users.update(userId, data);
await redis.del(`user:${userId}`);
}
// Rate limiting
async function rateLimit(ip, limit=100, window=60) {
const key = `ratelimit:${ip}`;
const count = await redis.incr(key);
if (count === 1) await redis.expire(key, window);
return count <= limit;
}
// Session storage (connect-redis)
import session from 'express-session';
import { RedisStore } from 'connect-redis';
app.use(session({
store: new RedisStore({ client: redis }),
secret: process.env.SESSION_SECRET,
resave: false, saveUninitialized: false,
cookie: { secure: true, maxAge: 86400000 }
}));
await redis.setex('key', 300, 'value'); // Set with 300s TTL
const ttl = await redis.ttl('key'); // Time remaining (-1=no expiry, -2=gone)
await redis.expire('key', 600); // Reset TTL without changing value
await redis.del('key'); // Delete immediately
| Mode | How | Durability |
|---|---|---|
| RDB | Point-in-time snapshot every N minutes | Low — lose data since last snapshot |
| AOF | Log every write command | High — can replay to any point |
| Both | RDB + AOF | Best — fast restarts + durability |
# docker-compose.yml (enables AOF persistence)
redis:
image: redis:7-alpine
command: redis-server --appendonly yes --save 60 1