Redis hit maxmemory at 3 AM and started evicting your session keys. Users were logged out. The fix wasn't more RAM — it was discovering that your application was storing 8KB JSON blobs when 200-byte hashes would do the same job. Here's how to audit, optimize, and right-size Redis memory usage.
- Use
MEMORY USAGE keyandredis-cli --bigkeysto find oversized keys - Hashes, lists, and sets with small counts use compact ziplist/listpack encoding — 5–10x smaller than individual strings
- Always set TTLs on non-permanent keys — missing TTLs are the #1 cause of unbounded Redis growth
- Choose the right
maxmemory-policyfor your workload:allkeys-lrufor caches,noevictionfor session stores
Finding Memory Hogs
Top-Level Memory Report
# Connect and check overall memory
redis-cli INFO memory
# Key fields:
# used_memory_human: how much Redis is using
# used_memory_peak_human: peak usage
# mem_fragmentation_ratio: ideal ~1.0-1.5; high = wasted memory from fragmentation
# maxmemory_human: your configured limit
# Find big keys (scans entire keyspace -- run on replica)
redis-cli --bigkeys
# Shows: top 10 largest keys per data type
# More detailed: sample 1% of keys
redis-cli --memkeys --memkeys-samples 100Inspect Individual Key Memory
# Memory used by a single key (including overhead)
redis-cli MEMORY USAGE user:session:abc123
# Returns bytes; typical small hash: 200-400 bytes
# Check encoding of a key
redis-cli OBJECT ENCODING user:session:abc123
# Compact encodings: ziplist, listpack, intset, embstr
# Expensive encodings: hashtable, skiplist, raw
# Debug object details
redis-cli DEBUG OBJECT user:session:abc123Encoding Optimization: The Big Win
Store Sessions as Hashes, Not JSON Strings
import redis
import json
r = redis.Redis()
# BAD: store session as JSON string
# Memory: ~500 bytes per session (JSON overhead + string key)
r.set('session:abc123', json.dumps({
'user_id': 42, 'role': 'admin', 'cart': [1, 2, 3], 'ip': '1.2.3.4'
}))
# GOOD: store session as Hash
# Memory: ~150 bytes per session (hash with ziplist encoding)
r.hset('session:abc123', mapping={
'user_id': 42, 'role': 'admin', 'ip': '1.2.3.4'
})
r.expire('session:abc123', 3600) # always set TTL!
# Even better: store cart separately with its own TTL
r.rpush('cart:42', 1, 2, 3)
r.expire('cart:42', 86400)Keep Hashes in Compact Encoding
# Hash uses ziplist/listpack (compact) when:
# field count <= hash-max-listpack-entries (default: 128)
# field value size <= hash-max-listpack-value (default: 64 bytes)
# redis.conf tuning for small hashes:
hash-max-listpack-entries 128
hash-max-listpack-value 64
# Verify encoding stays compact:
redis-cli OBJECT ENCODING session:abc123
# Should return: listpack (or ziplist on older Redis)
# NOT: hashtable (which uses 5-10x more memory)Eviction Policy Configuration
# Set maxmemory and eviction policy
redis-cli CONFIG SET maxmemory 8gb
redis-cli CONFIG SET maxmemory-policy allkeys-lru
# Eviction policies:
# noeviction -- return errors when full (use for session/queue stores)
# allkeys-lru -- evict least recently used (best for pure caches)
# volatile-lru -- evict LRU keys with TTL set (mixed workloads)
# allkeys-lfu -- evict least frequently used (Redis 4+, better for skewed access)
# volatile-ttl -- evict keys closest to expiry
# Persist to redis.conf
# maxmemory 8gb
# maxmemory-policy allkeys-lruUsing noeviction when Redis hits maxmemory causes all write commands to return OOM command not allowed errors. Your application must handle this gracefully. Use noeviction only for session and queue stores where losing data is worse than returning errors.
- Store structured data as Redis Hashes (not JSON strings) to use ziplist/listpack encoding — typically 5–10x smaller memory footprint.
- Run
redis-cli --bigkeyson replicas monthly to identify oversized keys before they exhaust maxmemory. - Set TTLs on every non-permanent key — missing TTLs are the most common cause of unbounded Redis growth.
- Choose
allkeys-lrufor pure cache workloads andnoevictionfor session stores where data loss is unacceptable.
Working with JusDB on Redis Optimization
JusDB audits Redis memory usage for engineering teams, identifies encoding inefficiencies, and implements TTL policies that right-size Redis deployments without hardware upgrades. We have consistently reduced Redis memory consumption by 40–70% through encoding and data model optimization.