Databases
Redis
Redis keeps its dataset in memory for very low-latency access, with data structures beyond plain key-value pairs — lists, sets, hashes, sorted sets, streams — and optional persistence to disk so a restart doesn't necessarily mean total data loss. It's most often deployed alongside a primary database rather than used as an application's sole source of truth.
Why it matters
- It makes caching a simple key lookup
- Instead of custom in-application caching logic, a value can be stored and fetched from Redis with a single command, with an expiry attached directly to the key.
- It's a common backing store for sessions and rate limiting
- Fast reads and writes, plus built-in expiry, make it a natural fit for short-lived data like login sessions or per-user request counters.
- Its data structures fit specific problems directly
- A sorted set is a natural fit for a leaderboard or ranking, and pub/sub gives a lightweight way to broadcast an event to multiple listeners without a full message broker.
Basic operations
Commands are simple and direct: set a value with an optional expiry, read it back, increment a counter atomically, or work with a richer structure like a sorted set.
SET session:42 "u_42" EX 3600
GET session:42
INCR pageviews:home
ZADD leaderboard 1500 "player7"
ZREVRANGE leaderboard 0 2 WITHSCORESPersistence: RDB, AOF, and what 'in-memory' really risks
Redis can snapshot its dataset to disk periodically (RDB) or log every write operation to an append-only file (AOF) so it can be replayed after a restart. Neither eliminates the risk entirely: RDB snapshots leave a window of recent writes that can be lost between snapshots, and even AOF, tuned for the strongest durability, trades some performance for that safety. This is why Redis is usually treated as a fast, secondary store rather than the only copy of important data.
Beyond caching: pub/sub, rate limiting, leaderboards
A sorted set naturally fits a ranked leaderboard, since it keeps members ordered by score with efficient range queries. An atomic increment with an expiry is a simple, effective building block for rate limiting. Redis's pub/sub lets one process publish a message that every subscribed process receives immediately, useful for lightweight real-time notifications without needing a dedicated message broker.
Mistakes people make here
- Treating Redis as a fully durable primary database without understanding the trade-off
- Even with persistence enabled, there's a real window in which recent writes can be lost on a crash unless AOF is tuned aggressively, and that tuning itself costs some of the performance that's the reason to use Redis in the first place.
- Storing data with no expiry
- Keys that never expire and are never explicitly deleted accumulate until they hit memory limits, at which point the server either evicts data (if configured to) or runs into an out-of-memory error.
- Using it for large blobs it wasn't designed for
- Redis is optimized for many small, fast operations on structured values, not for storing large files or blobs — that workload fits an object store or a database designed for large payloads better.
- Not planning for what happens when Redis is unavailable
- A cache-only outage should degrade gracefully back to the primary database, not take the whole application down; but if Redis is also the session store, its outage logging every user out is a design decision that needs to be made deliberately, not discovered during an incident.
Strengths and trade-offs
Where it is strong
- Very low latency, since data lives in memory rather than being read from disk on each access.
- Rich data structures — sorted sets, hashes, lists, streams — go well beyond plain key-value pairs.
- Doubles as a lightweight pub/sub mechanism or simple queue for real-time needs that don't require a full message broker.
- A simpler operational model for caching than standing up a full search or analytics engine for the same job.
The trade-offs
- Durability is opt-in and always a trade-off against speed — even with AOF enabled, there are windows where recent writes can be lost on a crash.
- Dataset size is bounded by available memory, which gets expensive at large scale compared to disk-based stores.
- No rich query language or joins — it's fast because the model is simple, not because it's a general-purpose database.
- Command execution per shard is effectively single-threaded, so one very slow command can hold up others queued behind it.
Who needs this
Relevant to anyone adding caching, session storage, rate limiting, or simple real-time features to an application backed by a primary database.
Questions about redis
- Is Redis a database or a cache?
- Both, depending on how it's used — most teams use it as a cache or a secondary store, but some use it as a primary store with persistence carefully tuned for that role.
- Can I lose data if Redis restarts?
- Yes, unless persistence (RDB snapshots or an append-only file) is configured, and even then there's a possible small window of loss depending on how aggressively that persistence is tuned.
- Is Redis the same as Memcached?
- They occupy a similar niche, but Redis has more data structures, optional persistence, and pub/sub built in, while Memcached is simpler and purely a cache with no persistence story at all.
- Does Redis support transactions?
- Yes, via MULTI and EXEC, but they're simpler than relational transactions — there's no automatic rollback if a command fails partway through, which is a real difference from how transactions behave in a relational database.