Redis is easy to start with and hard to run well at scale. This tutorial covers the practices that keep Redis fast, reliable, and secure in production.
Key Naming Conventions
Consistent key names make debugging and management much easier. Use colons as separators:
app:entity:identifier:field
Examples:
user:1001:profile
session:abc123
cache:product:5:details
rate:api:user:1001
lock:order:processing:42
Rules:
- Use lowercase
- Prefer colons over dots or hyphens (Redis treats colons as namespace separators in RedisInsight)
- Keep keys short — they add up in memory
- Include a TTL on anything that should expire
Memory Optimization
Redis stores everything in RAM. Know what you are using:
# Total memory info
INFO memory
# Memory per key (use sparingly in production)
MEMORY USAGE user:1001:profile
# Find the biggest keys
redis-cli --bigkeys
Choose the right data type:
- Store small integers as strings, not hashes
- Use hashes instead of many separate keys for object fields
- Use sorted sets instead of a list + separate score tracking
# Bad: 5 separate keys per user
SET user:1:name "Alex"
SET user:1:email "alex@example.com"
SET user:1:age "28"
SET user:1:city "Berlin"
SET user:1:score "1500"
# Good: one hash
HSET user:1 name "Alex" email "alex@example.com" age "28" city "Berlin" score "1500"
maxmemory and Eviction Policies
Set a memory limit to prevent Redis from consuming all available RAM:
# redis.conf or via command
CONFIG SET maxmemory 2gb
CONFIG SET maxmemory-policy allkeys-lru
Eviction policies (what to delete when memory is full):
| Policy | What it deletes |
|---|---|
noeviction | Returns error — never deletes (default) |
allkeys-lru | Least recently used key from all keys |
volatile-lru | LRU from keys with TTL set |
allkeys-lfu | Least frequently used from all keys |
volatile-ttl | Key with shortest TTL |
allkeys-random | Random key from all keys |
For a cache: use allkeys-lru or allkeys-lfu.
For a session store: use volatile-lru (only evict keys with TTL).
For a queue or stream: use noeviction (never lose messages).
Persistence: RDB vs AOF
Redis is in-memory, but you can persist data to disk.
RDB (Redis Database) — periodic snapshots:
# Save a snapshot every 60 seconds if at least 1 key changed
CONFIG SET save "60 1"
# Manual snapshot
BGSAVE
RDB is fast to load on startup but can lose up to 60 seconds of data on crash.
AOF (Append-Only File) — log every write command:
CONFIG SET appendonly yes
CONFIG SET appendfsync everysec # flush to disk every second
AOF loses at most 1 second of data but produces larger files and slower restarts.
Recommendation: Use both for production. RDB for fast restarts, AOF for minimal data loss.
Avoiding Common Pitfalls
KEYS command — scans the entire keyspace and blocks Redis:
# NEVER in production (blocks Redis for seconds)
KEYS user:*
# Use SCAN instead (non-blocking, cursor-based)
SCAN 0 MATCH user:* COUNT 100
Large keys — a key with millions of members in a set or sorted set blocks Redis during operations. Split large sets across multiple keys.
Hot keys — a single key receiving thousands of requests per second becomes a bottleneck. Add a random suffix to spread reads across multiple replicas, or use local in-process caching for extremely hot items.
ACL Security
Redis 8 supports fine-grained Access Control Lists:
# Create a read-only user
ACL SETUSER readonly on >password ~cache:* +GET +HGET +SMEMBERS +ZRANGE
# Create an app user with specific permissions
ACL SETUSER myapp on >apppassword ~* +@all -@dangerous
# List users
ACL LIST
# Test permissions
ACL WHOAMI
ACL CAT # list all command categories
Always set a password in production:
CONFIG SET requirepass "strong-random-password-here"
TLS Encryption
Enable TLS for connections between your application and Redis:
# redis.conf
tls-port 6380
tls-cert-file /path/to/redis.crt
tls-key-file /path/to/redis.key
tls-ca-cert-file /path/to/ca.crt
Managed Redis services (AWS ElastiCache, Upstash, Redis Cloud) handle TLS automatically.
Monitoring with INFO
# All stats
INFO all
# Specific sections
INFO memory # memory usage
INFO stats # operations per second, cache hit rate
INFO clients # connected clients
INFO replication # master/replica status
INFO keyspace # keys per database, expiration stats
Key metrics to monitor:
# Cache hit rate (should be > 90% for a cache)
INFO stats
# Look for: keyspace_hits / (keyspace_hits + keyspace_misses)
# Connected clients
INFO clients
# Look for: connected_clients
# Memory fragmentation ratio (ideally 1.0-1.5)
INFO memory
# Look for: mem_fragmentation_ratio
# Replication lag
INFO replication
# Look for: master_repl_offset vs slave_repl_offset
Redis Sentinel vs Cluster
Redis Sentinel — high availability for a single dataset:
- 3+ Sentinel nodes monitor the primary
- Auto-promotes a replica if primary fails
- Single node still limits to one machine’s RAM
Redis Cluster — horizontal scaling:
- Data is sharded across 3-6+ nodes
- Each node holds a subset of the keyspace (hash slots)
- Multi-key operations require keys to be in the same slot
- Use hash tags
{user}.sessionto keep related keys together
For most applications, a single primary + 1-2 replicas + Sentinel is enough. Use Cluster when your dataset exceeds the RAM of a single machine.
Managed Redis Services
| Service | Max memory | Persistence | Cluster |
|---|---|---|---|
| AWS ElastiCache | Up to 400 GB per node | ✅ | ✅ |
| Upstash | Serverless, pay per request | ✅ | - |
| Redis Cloud | Up to 50 TB | ✅ | ✅ |
| Fly.io Redis | Up to 10 GB | ✅ | - |
For most web applications, Upstash (serverless, free tier) or a small ElastiCache/Redis Cloud instance is the right choice.
What’s Next?
Redis is covered. Next: SQLite — the embedded database that powers mobile apps, edge computing, and small production workloads.
Next: Database Tutorial #17: SQLite — When and How to Use It