In This Article
- What Redis Is (and What It Is Not)
- Redis vs. Memcached: The Real Comparison
- Redis Data Structures Explained
- Caching Patterns: Cache-Aside, Write-Through, Write-Behind
- Redis as a Session Store
- Redis Pub/Sub for Real-Time Features
- Redis Streams for Event-Driven Architecture
- Redis for AI and LLM Applications
- Persistence: RDB Snapshots vs. AOF Logging
- The SSPL License Change and Valkey Fork
- Managed Redis: ElastiCache vs. Upstash vs. Redis Cloud
- Frequently Asked Questions
Key Takeaways
- What is Redis and what is it used for? Redis (Remote Dictionary Server) is an open-source, in-memory data structure store used as a database, cache, message broker, and streaming engine.
- Is Redis still open source after the SSPL license change? Redis changed its license from the permissive BSD license to the more restrictive Server Side Public License (SSPL) and Redis Source Available Lice...
- Redis vs Memcached — which should I use? For almost every new project in 2026, choose Redis. Memcached is a simpler, multi-threaded cache that does one thing extremely well — storing strin...
- What is the difference between Redis RDB and AOF persistence? Redis offers two persistence mechanisms. RDB (Redis Database) creates point-in-time snapshots of your dataset at configurable intervals — for examp...
If you have built a web application of any real scale, you have almost certainly encountered a Redis recommendation. Add Redis for caching. Add Redis for sessions. Add Redis for rate limiting. Add Redis for your job queue. The advice appears so frequently it starts to sound like a magic incantation — add Redis and your problems go away.
In practice, Redis is genuinely one of the most useful tools in backend engineering. But "add Redis" without understanding why leads to misconfigured deployments, unexpected data loss, and confusion about when Redis is the right tool versus when a different approach would serve you better. This guide cuts through the noise.
We will cover what Redis actually is, how its data structures work and when to use each one, the caching patterns that appear in virtually every production system, Redis's expanding role in AI and LLM applications, the persistence tradeoffs that determine your data durability story, the significant licensing change that took effect in 2024, and how to choose between the major managed Redis providers.
What Redis Is (and What It Is Not)
Redis is an in-memory data structure store that delivers sub-millisecond read/write latency (~1ms) and over 1 million operations per second on a single node — it is not a replacement for PostgreSQL or MongoDB, but rather a speed layer that serves three distinct roles: cache (expensive query results), session store (user auth state with auto-expiry), and message broker (Pub/Sub channels and persistent Streams).
Redis stands for Remote Dictionary Server. It was created by Salvatore Sanfilippo in 2009, initially to solve a specific problem with a real-time analytics system where relational databases were too slow. The key design decision — store everything in RAM rather than on disk — was what made Redis fast enough to matter, and what has defined it ever since.
Redis is primarily an in-memory data structure store. Every piece of data you write to Redis lives in the server's RAM, which is why reads and writes happen in microseconds rather than milliseconds. It is not a replacement for a relational database. It does not offer SQL queries, joins, or transactions in the traditional sense. What it offers is extreme speed for a well-defined set of operations on a rich set of data structures.
In modern architectures, Redis plays three distinct roles. As a cache, it stores the results of expensive database queries or API calls so subsequent requests can be served from memory. As a session store, it holds user session data that needs to be fast to read and automatically expire. As a message broker, it coordinates communication between services through Pub/Sub channels or persistent Streams. Many production systems use Redis for all three simultaneously.
"Redis is the duct tape of backend engineering — it solves a dozen different problems with the same tool, and it solves them faster than almost anything else you could reach for."
Redis vs. Memcached: The Real Comparison
Choose Redis over Memcached for all new projects in 2026 — Redis supports complex data structures (hashes, sorted sets, streams), persistence to disk, Pub/Sub, and Lua scripting that Memcached cannot do; Memcached only edges out Redis when you need to cache very large binary objects across many CPU cores and raw multi-threaded throughput is the only requirement.
Memcached predates Redis by four years — it was created at LiveJournal in 2003. For a long time, it was the default choice for application caching. Simple key-value storage, very fast, easily horizontally scaled across many servers. It did one thing and did it well.
The honest answer in 2026 is that Redis has superseded Memcached for almost every new project. The tradeoffs are real but narrow.
| Feature | Redis | Memcached |
|---|---|---|
| Data structures | Strings, hashes, lists, sets, sorted sets, streams, bitmaps, HyperLogLog | Strings only |
| Persistence to disk | Yes (RDB + AOF) | No — cache only |
| Pub/Sub messaging | Yes | No |
| Lua scripting | Yes | No |
| Multi-threading | Single-threaded core (I/O multi-threaded since v6) | True multi-threaded |
| Max object size | 512 MB per value | Configurable (default 1 MB, can go higher) |
| Cluster support | Redis Cluster (built-in) | Client-side sharding |
| Active community | Very active | Maintenance mode |
The one scenario where Memcached can still edge out Redis is when you need to cache very large binary objects across many CPU cores and raw horizontal throughput is the only thing that matters. Memcached's true multi-threaded architecture scales linearly with CPU cores in a way Redis does not. For 99% of applications — and especially for any new project in 2026 — choose Redis.
Redis Data Structures Explained
Redis's native data structures let you operate on data at the server level atomically — Sorted Sets for real-time leaderboards (ZADD/ZRANGEBYSCORE), Lists for job queues (LPUSH/BRPOP), Hashes for user objects (HSET/HGETALL), Sets for unique visitor counting, and HyperLogLog for approximate cardinality at constant memory — each structure has specific O(1) or O(log N) operations that application-level JSON blobs cannot match.
The feature that separates Redis from every other cache is its native support for complex data structures. You are not limited to storing serialized JSON blobs — Redis understands the shape of your data and can operate on it atomically at the server level, which is both faster and safer than doing the same work in your application code.
The Foundation
The simplest type — a key maps to a byte string up to 512 MB. Use for counters (INCR), simple cache values, feature flags, and any scalar data. Strings are the most memory-efficient Redis type.
Object Storage
A key maps to a map of field-value pairs — like a flat JSON object. Use for storing user profiles, product records, or any entity where you want to update individual fields without rewriting the whole object.
Ordered Sequences
A doubly-linked list of strings. O(1) push/pop from both ends makes Lists ideal for job queues (LPUSH / BRPOP), activity feeds capped to a recent window, and chat message history.
Unique Collections
An unordered collection with no duplicates. Powerful set operations — SUNION, SINTER, SDIFF — run server-side. Perfect for tagging systems, unique visitor counts, and social graph relationships.
Ranked Leaderboards
Like a Set, but each member has a floating-point score. Members are ordered by score. ZADD, ZRANGE, ZRANK power leaderboards, priority queues, and time-windowed rate limiting with microsecond precision.
Persistent Event Log
An append-only log with consumer group support — Redis's answer to a lightweight Kafka. Each entry has an auto-generated ID. Use for audit logs, IoT sensor data, event sourcing, and durable inter-service messaging.
Beyond these six core types, Redis also provides Bitmaps (per-bit operations on string values — used for compact boolean flags), HyperLogLog (probabilistic cardinality estimation for unique counts at massive scale), and Geospatial indexes (lat/lon coordinates with radius queries). Each type is implemented in a way that minimizes memory usage while maximizing operation speed.
Caching Patterns: Cache-Aside, Write-Through, Write-Behind
Cache-aside (lazy loading) is the default pattern — check Redis first, on miss fetch from database and write to cache with a TTL; write-through keeps cache always current but pays two writes per mutation; write-behind maximizes write throughput with async DB flush but risks data loss; cache-aside is resilient to Redis outages because misses fall through to the database automatically.
Knowing that Redis is fast is not enough — you need to know how to integrate it into your application's data layer. Three patterns cover the vast majority of production caching scenarios.
Cache-Aside (Lazy Loading)
Cache-aside is the most common pattern. Your application checks the cache first. On a cache hit, data is returned immediately. On a cache miss, the application fetches the data from the primary database, writes it to the cache with a TTL (time-to-live), and returns it. Redis is only populated with data that is actually requested — nothing more.
async function getUserById(userId) {
const cacheKey = `user:${userId}`;
// 1. Check cache
const cached = await redis.get(cacheKey);
if (cached) return JSON.parse(cached);
// 2. Cache miss — fetch from DB
const user = await db.users.findById(userId);
// 3. Write to cache with 5-minute TTL
await redis.set(cacheKey, JSON.stringify(user), 'EX', 300);
return user;
}
Cache-aside is resilient — if Redis goes down, requests simply fall through to the database. The main downside is the first request after a TTL expiry pays the full database penalty (the "thundering herd" problem under high traffic, addressed with probabilistic early expiration or a cache lock).
Write-Through
In write-through caching, every write to the database is simultaneously written to the cache. The cache is always up to date. There is no cache miss after a write, but you pay the latency cost of two writes on every mutation, and you cache data that may never be read again.
Write-Behind (Write-Back)
Write-behind decouples the write path: the application writes to the cache immediately and returns success. Redis then asynchronously flushes the data to the primary database in the background. This delivers the lowest write latency possible but introduces a window of potential data loss if Redis crashes before flushing. Use write-behind only where sub-millisecond write acknowledgment matters and a small loss window is tolerable (click counters, view counts, non-critical analytics).
Choosing the Right Pattern
- Cache-Aside: Default choice for read-heavy workloads. Simple to implement. Resilient to cache failures.
- Write-Through: Best when stale data is unacceptable and write frequency is low relative to reads.
- Write-Behind: Only where maximum write throughput matters and temporary data loss is tolerable.
Redis as a Session Store
Redis is the industry standard for session storage — store the session token as a Redis key with user data as the value and a TTL matching your session policy; sub-millisecond lookups add negligible overhead, and unlike cookie-only sessions, Redis enables instant revocation (delete the key), multi-device session management, and distributed sharing across multiple app servers without sticky load balancing.
HTTP is stateless. Every modern web application that has user authentication needs somewhere to store session state between requests. The three options are: in the database (slow), in a signed cookie (limited size, no server-side revocation), or in Redis (fast, flexible, revocable).
Redis is the industry standard for session storage in Node.js, Python/Django/Flask, and Ruby on Rails applications. The pattern is simple: when a user logs in, generate a session token, store it as a Redis key with the user's data as the value, and set a TTL matching your session expiration policy. On each request, validate the token against Redis — the sub-millisecond lookup adds negligible overhead.
import session from 'express-session';
import RedisStore from 'connect-redis';
import { createClient } from 'redis';
const redisClient = createClient({ url: process.env.REDIS_URL });
await redisClient.connect();
app.use(session({
store: new RedisStore({ client: redisClient }),
secret: process.env.SESSION_SECRET,
resave: false,
saveUninitialized: false,
cookie: {
secure: process.env.NODE_ENV === 'production',
httpOnly: true,
maxAge: 1000 * 60 * 60 * 24 // 24 hours
}
}));
With Redis handling sessions, you can also implement instant session revocation (delete the key), multi-device session management (namespaced keys per device), and distributed session sharing across multiple application servers without sticky load balancing. These are capabilities that cookie-only sessions simply cannot provide.
Redis Pub/Sub for Real-Time Features
Redis Pub/Sub is fire-and-forget — publishers send to named channels, active subscribers receive immediately, offline subscribers miss the message entirely; use it for live notifications, chat presence, typing indicators, and real-time score updates where the latest state matters but missing a past message is acceptable; for durable messaging with persistence, use Redis Streams instead.
Redis Pub/Sub is a fire-and-forget messaging system built on a channel model. Publishers send messages to a named channel. Subscribers that are currently listening on that channel receive the message. If a subscriber is offline when the message is sent, it never sees it — Pub/Sub has no message persistence.
This makes Redis Pub/Sub ideal for real-time broadcast scenarios: live notifications, chat typing indicators, collaborative editing presence, live sports scores, or any case where the latest state matters but missing a message is acceptable. For more durable inter-service communication, use Redis Streams instead.
// Publisher (e.g., triggered when a new order arrives)
const publisher = createClient();
await publisher.connect();
await publisher.publish('orders:new', JSON.stringify({
orderId: '9f3a',
userId: '42',
total: 149.99
}));
// Subscriber (e.g., WebSocket server broadcasting to browser)
const subscriber = createClient();
await subscriber.connect();
await subscriber.subscribe('orders:new', (message) => {
const order = JSON.parse(message);
io.to(`user:${order.userId}`).emit('order_update', order);
});
One practical consideration: Redis Pub/Sub does not scale fan-out to millions of subscribers the way specialized streaming platforms do. For large-scale notification systems, you will eventually need to shard channels or use a dedicated platform. But for most applications handling tens of thousands of concurrent connections, Redis Pub/Sub is fast, simple, and already in your stack.
Redis Streams for Event-Driven Architecture
Redis Streams are a persistent, append-only log with consumer groups — messages stay in the stream until explicitly trimmed, consumers can replay from any point in history, and consumer groups distribute processing across multiple consumers exactly like Kafka consumer groups, at dramatically lower operational complexity; start with Streams and graduate to Kafka only when you need multi-region replication or months of log retention.
Redis Streams, introduced in Redis 5.0, address the key limitation of Pub/Sub: persistence. A Stream is an append-only log — messages are written with an auto-generated timestamp ID and remain in the stream until explicitly trimmed. Consumers can read from any point in history, replay events, and acknowledge processing.
Streams support consumer groups — multiple consumers that share the work of processing messages, with Redis tracking which messages have been delivered and acknowledged. This is the same model as Kafka consumer groups, at dramatically lower operational complexity.
Redis Streams vs. Kafka: When to Use Each
- Use Redis Streams when you need lightweight, fast event passing between services in the same stack, do not need multi-month retention, and want operational simplicity. Ideal for inter-service messaging, audit logs, and event sourcing at moderate scale.
- Use Kafka when you need multi-region replication, months of log retention, massive throughput (millions of events/sec), or complex stream processing with tools like Flink or ksqlDB. Kafka adds substantial operational complexity — it earns its place at scale.
For most applications that are not yet at Kafka scale, Redis Streams deliver 80% of the capability at a fraction of the infrastructure cost. Start with Streams. Graduate to Kafka when you have a specific need that Streams cannot meet.
Redis for AI and LLM Applications
Redis serves three roles in AI/LLM applications: semantic caching of LLM responses (reducing OpenAI/Anthropic API costs by 30–70% by returning cached answers for semantically similar queries), atomic rate limiting of AI API calls (sliding window with INCR/ZRANGEBYSCORE, race-condition-free across multiple servers), and in-memory vector search for RAG pipelines where sub-millisecond retrieval speed matters more than storage cost.
Redis has become an increasingly critical piece of AI application infrastructure. Three use cases now appear in nearly every production LLM-powered application.
Caching LLM Responses
LLM API calls — to OpenAI, Anthropic, Google, or any hosted model — are expensive and slow by application standards. A GPT-4o call can take 2–8 seconds and cost $0.01–$0.10 depending on token count. When users ask semantically identical questions, re-calling the API wastes both money and time.
Redis enables semantic caching: generate an embedding for the incoming query, look up nearby embeddings in a Redis vector index (using the RediSearch module or Redis Stack), and return the cached response if a sufficiently similar query has been answered before. For applications where many users ask similar questions — customer support bots, document Q&A systems, coding assistants — this can reduce LLM API costs by 30–70%.
Rate Limiting API Calls
Redis Sorted Sets and the atomic INCR command make it trivial to implement sliding window rate limiting — enforcing that a user makes no more than N API calls per minute, per hour, or per day. Because Redis operations are atomic, you get race-condition-free rate limiting across multiple application servers without database locks.
// Allow 100 requests per user per 60-second window
async function checkRateLimit(userId) {
const key = `rate:${userId}`;
const now = Date.now();
const window = 60_000; // 60 seconds in ms
const limit = 100;
await redis.zRemRangeByScore(key, 0, now - window);
const count = await redis.zCard(key);
if (count >= limit) return { allowed: false, remaining: 0 };
await redis.zAdd(key, { score: now, value: `${now}` });
await redis.expire(key, 70);
return { allowed: true, remaining: limit - count - 1 };
}
Vector Search and RAG Pipelines
Redis Stack includes RediSearch, which supports vector similarity search. In a Retrieval-Augmented Generation (RAG) pipeline, document embeddings are stored as Redis vectors. When a query arrives, its embedding is compared against the stored vectors to retrieve the most relevant document chunks, which are then injected into the LLM prompt as context. Redis's in-memory vector search delivers results in under a millisecond — far faster than pgvector on a busy PostgreSQL instance.
Persistence: RDB Snapshots vs. AOF Logging
Use both RDB and AOF in production: RDB (point-in-time binary snapshots) for fast disaster recovery and startup, AOF (append-only write log with 1-second fsync) for durability that limits data loss to at most one second; RDB alone is sufficient for pure caches where data loss is acceptable, but session stores and queues require AOF to avoid losing state on crash.
Redis is primarily an in-memory store, but it offers two mechanisms for persisting data to disk. Understanding the tradeoff between them is essential for any production deployment.
RDB — Redis Database Snapshots
RDB creates a point-in-time binary snapshot of your entire dataset at configurable intervals. You can set rules like "save if 1,000 keys have changed in the last 15 minutes." RDB files are compact, fast to write (Redis forks a child process so the parent keeps serving requests), and very fast to restore on startup. The tradeoff is that you can lose up to the snapshot interval's worth of data if Redis crashes between snapshots.
AOF — Append-Only File
AOF logs every write command to a file on disk. On restart, Redis replays the log to reconstruct the dataset. You can configure AOF to fsync every second (at most 1 second of data loss), or on every write (no data loss, but slower). AOF files grow over time and are periodically compacted by a background rewrite process. AOF provides much stronger durability guarantees than RDB.
| Property | RDB Snapshots | AOF Logging |
|---|---|---|
| Durability | Up to interval's worth of data loss | At most 1 second (or 0 with every-write fsync) |
| Performance impact | Minimal — child process handles snapshots | Slight overhead on every write |
| File size | Compact binary format | Larger — grows until rewrite |
| Restart speed | Fast — load binary file | Slower — must replay all commands |
| Best for | Caches where occasional data loss is acceptable | Session stores, queues, anything requiring durability |
Most production deployments use both RDB and AOF together: RDB for fast disaster recovery and AOF for fine-grained durability. This is the Redis documentation's recommended configuration for any data you cannot afford to lose.
The SSPL License Change and the Valkey Fork
Redis changed from BSD to SSPL licensing in March 2024 — this does not affect developers building applications on top of Redis, only cloud providers offering it as a service; for teams requiring an OSI-approved open-source license, Valkey (Linux Foundation fork backed by AWS, Google, Oracle) is a BSD-licensed, drop-in compatible alternative available on ElastiCache and other managed platforms.
In March 2024, Redis Ltd. changed the license for Redis 7.4 and all future versions from the open BSD-2-Clause license to a dual license under the Server Side Public License (SSPL) and the Redis Source Available License (RSAL). This was a significant move that sent shockwaves through the open-source community.
What the License Change Actually Means
The SSPL is specifically designed to prevent cloud providers from offering Redis as a managed service without contributing back to the project or obtaining a commercial license. If you are a developer building applications on top of Redis, the license change does not affect you. You can continue to use Redis freely.
The change matters if you are a cloud provider, a SaaS company offering Redis-as-a-service to others, or an organization with a policy requiring OSI-approved open-source licenses throughout the stack.
The response from the open-source community was swift. Within weeks of the announcement, the Linux Foundation announced Valkey — a community-maintained fork of Redis 7.2.4 (the last BSD-licensed version), backed by AWS, Google Cloud, Oracle, Ericsson, Snap, and others. Valkey is BSD-licensed, drop-in compatible with Redis clients and commands, and actively maintained. Redis 7.2 and Valkey are functionally identical for the vast majority of use cases.
AWS ElastiCache and MemoryDB now offer Valkey as a managed option. Upstash's serverless product supports the Redis API. For new projects with open-source license requirements, Valkey is the clean choice. For existing projects, Redis works exactly as it always has — the license change has no operational implications if you are just using it.
Learn Redis, Docker, and AI tools in two intensive days
The Precision AI Academy bootcamp covers Redis, Python, APIs, cloud deployment, and building AI-powered applications — hands-on, not lecture-only. Five cities. October 2026.
Reserve Your Seat — $1,490Managed Redis: ElastiCache vs. Upstash vs. Redis Cloud
Choose ElastiCache for AWS-native production workloads needing VPC isolation and IAM auth; Upstash for serverless/edge architectures (Vercel, Cloudflare Workers) where pay-per-request pricing and REST API access matter; Redis Cloud for AI applications requiring the full Redis Stack with vector search; Valkey on ElastiCache for teams with open-source license requirements.
Running Redis in production means choosing between self-managed (you own the ops), or handing that work to a managed provider. For most teams, managed is the right call. Here is how the three dominant options compare.
AWS ElastiCache
Fully managed Redis (and now Valkey) inside your VPC. Best network performance for EC2-hosted apps. Multi-AZ replication, automated failover, cluster mode. Pricing is instance-based — you pay for provisioned capacity whether you use it or not. Not cost-effective at low usage.
Upstash
Serverless Redis — you pay per request, with a generous free tier. Zero configuration, global replication, REST API for edge environments. Perfect for Next.js on Vercel, Cloudflare Workers, and any serverless architecture. Can get expensive at very high request volumes.
Redis Cloud
Managed Redis from the original Redis team. Supports the full Redis Stack (RediSearch, RedisJSON, vector search). Multi-cloud, active-active geo-replication. Best option when you need Redis modules like vector similarity search for RAG pipelines.
For teams on AWS running standard caching and sessions, ElastiCache or ElastiCache Serverless is the simplest path. For serverless and edge-first architectures, Upstash has no real competition. For AI applications needing vector search and full Redis Stack features, Redis Cloud is the most capable option.
Quick Decision Guide
- Startup on Vercel/Netlify: Upstash — serverless pricing, zero ops, free tier
- Enterprise on AWS: ElastiCache — VPC isolation, IAM auth, multi-AZ
- AI/LLM app needing vector search: Redis Cloud with Redis Stack
- Open-source license required: Self-managed Valkey on EC2 or EKS, or ElastiCache Valkey
- Learning / side projects: Redis Cloud Free Tier (30 MB) or local Docker
The bottom line: Redis belongs in nearly every production backend stack as the speed layer between your application and your primary database — use it for caching, sessions, and rate limiting by default, add Pub/Sub for real-time features and Streams for lightweight event-driven architectures, and lean on its vector search capabilities for AI/LLM applications where retrieval latency matters; deploy managed (Upstash for serverless, ElastiCache for AWS) and enable both RDB and AOF for anything you cannot afford to lose.
Frequently Asked Questions
What is Redis and what is it used for?
Redis (Remote Dictionary Server) is an open-source, in-memory data structure store used as a database, cache, message broker, and streaming engine. Its primary advantage is speed — because all data lives in RAM, Redis can serve hundreds of thousands of read and write operations per second with sub-millisecond latency. Common use cases include application caching, session storage, rate limiting, real-time leaderboards, Pub/Sub messaging, job queues, and increasingly, caching responses from large language models to reduce AI API costs.
Is Redis still open source after the SSPL license change?
Redis changed its license from the permissive BSD license to the more restrictive Server Side Public License (SSPL) and Redis Source Available License (RSAL) in March 2024, starting with Redis 7.4. This does not affect developers building applications on top of Redis — you can still use Redis freely in your applications. The change primarily targets cloud providers running Redis as a managed service without contributing back. For teams requiring an OSI-approved open-source license, the Valkey fork — maintained by the Linux Foundation with backing from AWS, Google, Oracle, and others — is a fully open-source, BSD-licensed drop-in alternative.
Redis vs. Memcached — which should I use?
For almost every new project in 2026, choose Redis. Memcached is a simpler, multi-threaded cache that stores string key-value pairs and scales linearly with CPU cores. Redis supports that and much more: rich data structures, persistence to disk, pub/sub messaging, Lua scripting, and clustering. The only scenario where Memcached can edge out Redis is caching very large binary objects across many CPU threads where raw horizontal scaling is the only constraint. For everything else — sessions, rate limiting, real-time features, leaderboards, AI response caching — Redis is the right choice.
What is the difference between Redis RDB and AOF persistence?
Redis offers two persistence mechanisms. RDB creates point-in-time binary snapshots of your dataset at configurable intervals — compact, fast to restore, but you can lose up to the interval's worth of writes if Redis crashes. AOF logs every write command to disk, giving you much finer durability — configure it to fsync every second (at most 1 second of data loss) or on every write. Most production deployments use both: RDB for fast disaster recovery restores and AOF for durability between snapshots.
Put Redis into practice — build something real
The Precision AI Academy bootcamp puts Redis, Python, Docker, and modern AI tools into a project you build yourself over two days. No slides-only lectures. Real infrastructure, real code, real skills.
View Bootcamp Details