Redis is an in-memory data store used for caching, sessions, rate limiting, queues, and real-time features. It handles millions of operations per second with sub-millisecond latency.
Quick Start
# Docker
docker run -d --name redis -p 6379:6379 redis:7-alpine
# Connect
docker exec -it redis redis-cliData Types
Strings
SET user:1:name "Alice"
GET user:1:name # "Alice"
SET counter 0
INCR counter # 1
INCRBY counter 10 # 11
SET session:abc123 '{"userId":1}' EX 3600 # Expires in 1 hour
TTL session:abc123 # Seconds remainingHashes
HSET user:1 name "Alice" email "alice@example.com" role "admin"
HGET user:1 name # "Alice"
HGETALL user:1 # All fields
HINCRBY user:1 login_count 1Lists
LPUSH queue:emails '{"to":"alice","subject":"Welcome"}'
LPUSH queue:emails '{"to":"bob","subject":"Welcome"}'
RPOP queue:emails # Process oldest first (FIFO)
LLEN queue:emails # Queue lengthSets
SADD tags:post:1 "devops" "kubernetes" "docker"
SMEMBERS tags:post:1 # All tags
SISMEMBER tags:post:1 "kubernetes" # 1 (true)
SINTER tags:post:1 tags:post:2 # Common tagsSorted Sets
ZADD leaderboard 100 "alice" 85 "bob" 92 "charlie"
ZREVRANGE leaderboard 0 2 WITHSCORES # Top 3
ZINCRBY leaderboard 15 "bob" # Update score
ZRANK leaderboard "alice" # Rank (0-based)Caching Patterns
Cache-Aside (Lazy Loading)
async function getUser(id: string) {
// 1. Check cache
const cached = await redis.get(`user:${id}`);
if (cached) return JSON.parse(cached);
// 2. Cache miss — fetch from database
const user = await db.users.findUnique({ where: { id } });
// 3. Store in cache with TTL
await redis.set(`user:${id}`, JSON.stringify(user), 'EX', 3600);
return user;
}Write-Through
async function updateUser(id: string, data: Partial<User>) {
// 1. Update database
const user = await db.users.update({ where: { id }, data });
// 2. Update cache immediately
await redis.set(`user:${id}`, JSON.stringify(user), 'EX', 3600);
return user;
}Cache Invalidation
async function deleteUser(id: string) {
await db.users.delete({ where: { id } });
await redis.del(`user:${id}`);
// Also invalidate related caches
await redis.del(`user:${id}:posts`);
await redis.del(`user:${id}:settings`);
}Master this topic with hands-on labs
Go beyond reading — build real projects in sandboxed environments with expert video guidance.
Browse Courses →Session Storage
import RedisStore from 'connect-redis';
import session from 'express-session';
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: { maxAge: 86400000 }, // 24 hours
}));Rate Limiting
async function rateLimit(ip: string, limit = 100, windowSec = 60) {
const key = `ratelimit:${ip}`;
const current = await redis.incr(key);
if (current === 1) {
await redis.expire(key, windowSec);
}
if (current > limit) {
const ttl = await redis.ttl(key);
throw new Error(`Rate limited. Retry in ${ttl}s`);
}
return { remaining: limit - current, limit };
}Sliding Window (More Precise)
async function slidingWindowRateLimit(key: string, limit: number, windowMs: number) {
const now = Date.now();
const windowStart = now - windowMs;
await redis
.multi()
.zremrangebyscore(key, 0, windowStart) // Remove old entries
.zadd(key, now, `${now}`) // Add current request
.zcard(key) // Count requests in window
.expire(key, Math.ceil(windowMs / 1000))
.exec();
const count = await redis.zcard(key);
return count <= limit;
}Pub/Sub
// Publisher
await redis.publish('notifications', JSON.stringify({
userId: 1,
message: 'Your build completed',
}));
// Subscriber
const subscriber = redis.duplicate();
await subscriber.connect();
subscriber.subscribe('notifications', (message) => {
const data = JSON.parse(message);
console.log(`Notification for user ${data.userId}: ${data.message}`);
});Get weekly IT automation tips
Docker, Ansible, Terraform, MLOps — curated insights delivered to your inbox. No spam.
Subscribe Free →Production Configuration
# redis.conf
maxmemory 256mb
maxmemory-policy allkeys-lru
# Persistence
save 900 1 # Save if 1 key changed in 900s
save 300 10 # Save if 10 keys changed in 300s
appendonly yes
appendfsync everysec
# Security
requirepass your-strong-password
rename-command FLUSHALL ""
rename-command FLUSHDB ""Docker Compose
services:
redis:
image: redis:7-alpine
command: redis-server /usr/local/etc/redis/redis.conf
volumes:
- redis-data:/data
- ./redis.conf:/usr/local/etc/redis/redis.conf
ports:
- "6379:6379"
deploy:
resources:
limits:
memory: 512M
volumes:
redis-data:Monitoring
redis-cli INFO stats # Hit rate, connections, memory
redis-cli INFO memory # Memory breakdown
redis-cli SLOWLOG GET # Slow queries
redis-cli MONITOR # Live command stream (debug only!)Key metrics to track:
- used_memory — Current memory usage
- keyspace_hits / keyspace_misses — Cache hit ratio
- connected_clients — Active connections
- evicted_keys — Keys removed due to memory pressure
What's Next?
Our Node.js REST APIs course covers Redis caching, sessions, and rate limiting in production Node.js apps. Docker Fundamentals teaches containerized Redis deployment. First lessons are free. -e ---
Ready to go deeper? Explore our hands-on DevOps courses — practical labs covering Docker, Ansible, Terraform, and more.
Ready to learn by doing?
Stop reading tutorials — start building. Expert video courses with hands-on labs in real sandboxed environments.
Related Articles
Docker Compose for Dev Environments
Set up reproducible local development environments with Docker Compose. Multi-service stacks, hot reload, database seeding, and team workflows.
INP Core Web Vitals Guide 2026
Master Interaction to Next Paint (INP), the Core Web Vital that replaced FID. How to measure, diagnose, and fix poor INP scores.
Python for DevOps Automation
Python for DevOps automation. HTTP API clients, file processing, AWS boto3, subprocess management, and CLI tools for infrastructure.
Renovate Automated Dependency Updates
Renovate automatically creates pull requests for dependency updates across npm, pip, Docker, Terraform, and Helm. Learn how to configure Renovate for safe.
Rocky Linux vs AlmaLinux 2026
A practical comparison of Rocky Linux and AlmaLinux — the two leading RHEL-compatible distributions. Which CentOS successor should you choose?
Rook Ceph Kubernetes Storage Guide
Rook deploys Ceph distributed storage on Kubernetes for block, file, and object storage. Learn how to set up Rook-Ceph for persistent volumes, shared.
Explore topics
Browse more articles on the topics covered here.