backend
Redis is a cache, but that's not why I need it
Redis is a cache, but that's not why I need it
Redis usually gets introduced as a cache. Its more important role in my stack is the shared state layer that lets multiple backend instances and websocket connections coordinate — specifically as the adapter backing Socket.io's cross-instance pub/sub.
Without it, realtime messaging only works with a single instance. The moment there's more than one behind a load balancer, a message from a user on instance A never reaches a recipient on instance B, and nothing anywhere tells you it went nowhere.
I use ioredis over the simpler node-redis for strong TypeScript support, built-in cluster/sentinel support if it ever needs to scale past one node, and because @socket.io/redis-adapter expects it.
What the adapter fixes
Socket.io keeps room membership in a single process's memory by default. With one instance that's fine. With more than one — normal for scale and for zero-downtime deploys — each instance only knows its own connections. The Redis adapter has every instance publish emitted events to a shared pub/sub channel, so an emit on instance A fans out through Redis to instance B, which delivers to its own local sockets. That's what makes "admin on server A and user on server B message each other live" actually work.
Other natural fits: rate-limit counters that need to live somewhere shared rather than in each instance's local memory; caching token_version lookups with a short TTL so every authenticated request doesn't hit the database; presence tracking for read receipts or "active now" indicators.
The mental model
Redis is fast because it's in-memory, which is also its constraint. Don't treat it as durable for anything you can't afford to lose on a restart or eviction, unless it's explicitly configured for persistence. Every role Redis plays here — pub/sub, rate limits, cache — is fine to lose and rebuild. The source of truth for anything durable stays in Postgres. (I did once ship Redis on its default eviction policy while it was holding security tokens and rate-limit counters — under memory pressure it would silently drop one. Now it's noeviction, with a CI smoke test asserting that.)