Concept
In-Memory Key-Value Storage
Traditional databases (Postgres, MongoDB) write transactions to disk, which limits query speeds due to disk I/O latency.
Redis stores all data directly in RAM, achieving sub-millisecond read/write operations. It represents data in key-value format, supporting advanced types (Strings, Hashes, Lists, Sets, Sorted Sets).
Common Use Cases
- Cache-Aside Pattern: Reduces primary database load by caching query results.
// Check cache first const cachedUser = await redis.get(`user:${id}`); if (cachedUser) return JSON.parse(cachedUser); // Fallback to database const user = await db.users.findUnique({ where: { id } }); // Save to cache with Time-To-Live (TTL) expiry await redis.set(`user:${id}`, JSON.stringify(user), 'EX', 3600); // Expiries in 1 hour return user; - Session Store: Keeps user login sessions globally accessible across separate stateless web servers.
- Pub/Sub (Publish/Subscribe): Serves as a real-time event broker. Subscribers listen to channels for instant updates:
// Subscriber redis.subscribe('chat-room-1'); redis.on('message', (channel, msg) => { ... }); // Publisher redis.publish('chat-room-1', 'Hello world!');
Common Mistakes
1. Caching values without setting a Time-To-Live (TTL) expiry
If you write keys to Redis without setting an expiration (EX or PX), the data remains in memory forever. This leads to memory leaks (exhausting Redis RAM) and serves stale data indefinitely. Always set a logical TTL expiry.
2. Treating Redis as a primary durable database
Although Redis supports persistence options (RDB snapshots and AOF logs), writing to disk degrades its performance. Do not use Redis as the primary source of truth for critical data (like financial ledgers).
Best Practices
- Eviction Policies: Configure your Redis server with a
maxmemory-policylikeallkeys-lru(Least Recently Used) to automatically delete old keys when RAM is full. - Cache Invalidation: Explicitly delete cached keys (e.g.
redis.del('user:1')) whenever the underlying database record is updated or deleted. - Connection Reuse: Avoid opening a new Redis client connection on every request; maintain a single global connection client instance.
