← Stackzilla Blog
Redis: More Than a Cache
Published May 4, 2026
· 6 min read
· Redis, caching, databases, backend, performance, architecture
Redis ships in most stacks as a cache layer in front of a primary database. That is a legitimate use case. But treating Redis as only a cache is like owning a Swiss Army knife and only using it to open bottles.
Redis is in most production stacks, and in most of them it is doing one thing: caching. A query runs, the result gets stored in Redis with an expiration time, and the next request skips the database entirely. That is a legitimate use case and worth having. But treating Redis as only a cache is significantly underselling what it can do.
The data structures Redis exposes — strings, hashes, lists, sets, sorted sets, streams, and more — enable patterns that would be slow, expensive, or architecturally awkward to implement on a relational database. Teams that understand these patterns use Redis to solve problems they would otherwise add entire services or databases to address.
**Session Storage**
This is the first expansion most teams make beyond caching. Sessions need fast reads, automatic expiration, and enough durability to survive a process restart without justifying full relational storage. Redis handles all of this cleanly.
The TTL-based key expiration means sessions clean themselves up automatically. There is no scheduled job running DELETE on a sessions table. There is no growing table of stale session rows that someone will eventually have to clean up. You set an expiration when you write the session, and Redis handles the rest.
For applications using Express, Django, Rails, or any other web framework with session middleware, Redis session stores are well-supported and straightforward to configure. The switch from database-backed sessions to Redis sessions often improves response time measurably on applications with significant authenticated traffic.
**Rate Limiting**
The INCR command — which atomically increments a key and returns the new value — combined with EXPIRE gives you a working rate limiter in two Redis operations. For a fixed window approach: increment the counter for a user-and-window key, set an expiration on first increment, and reject requests where the counter exceeds the limit.
Sliding window rate limiting uses sorted sets. You store request timestamps as scores, remove entries outside the window with ZREMRANGEBYSCORE, count remaining entries with ZCARD, and allow or reject based on the count. The entire operation runs as a Lua script for atomicity.
This approach handles rate limiting without a single query hitting your primary database, which matters when rate limiting is applied to every incoming request.
**Pub/Sub and Message Queues**
Redis Pub/Sub provides a fast event broadcasting mechanism for applications that need real-time updates between services or between a server and connected clients. A service publishes to a channel; all subscribers receive the message instantly.
The limitation of basic Pub/Sub is that messages are not persisted. If a subscriber is offline when a message is published, it is lost. Redis Streams, introduced in Redis 5.0, address this. Streams provide a persistent, ordered log of events with consumer group support. Multiple consumers can read from the same stream, with Redis tracking which messages each consumer has processed. Failed processing can be retried by reclaiming unacknowledged messages.
For teams already running Redis who need a lightweight queue without the operational complexity of Kafka or RabbitMQ, Streams cover a significant portion of the use case. Not everything needs a dedicated message broker.
**Leaderboards and Ranked Data**
Sorted sets are the canonical Redis data structure for leaderboards. Each member has an associated score. ZADD adds or updates members with their scores. ZRANK returns a member's rank. ZRANGE retrieves members in order. ZREVRANGE retrieves them in reverse order. All of these operations run in O(log n) time.
For anything requiring a ranked view — game leaderboards, engagement rankings, trending content feeds, user reputation scores — sorted sets are significantly faster than running ORDER BY on a SQL table at query time, particularly as the dataset grows.
**Distributed Locking**
Redis provides a mechanism for distributed locks through the SET command with NX (set if not exists) and PX (expiration in milliseconds) options. The Redlock algorithm, though debated in distributed systems circles, is widely used for coordinating work across multiple application instances when exactly-one-execution guarantees are needed.
Common use cases include preventing duplicate processing of scheduled jobs, coordinating resource allocation across horizontally scaled services, and protecting critical sections that must not run concurrently.
**Full-Text Search**
Redis Stack includes RediSearch, a capable search engine built on top of Redis. For teams already operating Redis who need search functionality without adding Elasticsearch or a dedicated search service, RediSearch covers a meaningful slice of the use case — full-text search, filtering, sorting, and aggregation on indexed data.
It is not a replacement for Elasticsearch at scale, but for search over smaller datasets or internal tooling, it removes the need to operate a separate service.
**The Durability Question**
Redis is an in-memory store by default. Without persistence configuration, a restart means data loss. Two persistence options are available: RDB snapshots (periodic point-in-time dumps to disk) and AOF (append-only file that logs every write operation).
For caching use cases, persistence is usually unnecessary — the cache can be rebuilt from the primary database after a restart. For sessions, queues, or any data that is not purely derivative, understanding and configuring persistence appropriately is important before relying on Redis in production.
**The Honest Take**
Redis earns its place in a production stack well beyond caching. The teams that get the most value from it are the ones who have invested time in understanding which data structure solves which problem. The overhead of running Redis is low; the overhead of understanding it is an afternoon of reading. The return on that investment shows up consistently in simpler architectures, faster response times, and fewer separate services.
Read the full article on Stackzilla →