Redis anti-patterns.
KEYS in prod
KEYS user:*
Blocks server for size of dataset. Use SCAN.
SMEMBERS on huge set
SMEMBERS huge_set
Returns all members. Use SSCAN.
ZRANGE 0 -1 on huge zset
Returns everything. Use LIMIT and pagination.
Huge value
Single 100MB string blocks server during read.
No TTL on cache
Memory leak.
Using lists as queues without trimming
Lists grow unbounded.
Pub/sub for important events
Lost on disconnect. Use Streams.
DELETE huge keys
DEL on huge set: blocking. Use UNLINK (async).
Storing serialized objects when hashes work
SET user:1 '{"name":"a","age":30}'
vs
HSET user:1 name "a" age 30
Hash easier to read fields, often smaller.
Multi-DB usage
SELECT 1
SET ...
Multi-DB confusing + not cluster-compatible. Use key prefixes.
Long-running Lua scripts
Block entire server. Keep scripts fast.
MONITOR in prod
Logs every command. Heavy. Debugging only.
FLUSHALL by accident
DBSIZE → 1000000
FLUSHALL → 0
Add ACL restrictions.
Same Redis for everything
Cache + queue + sessions + pubsub. Noisy neighbor. Separate by use.
Persistence on cache-only
If pure cache: save "" + appendonly no. Less I/O.
No max-memory
maxmemory 0 # unlimited; default
OOM kills.
Forgetting WAIT for durability
SET k v
# Replica might not have it; primary crash → lost.
WAIT 1 1000
SUNIONSTORE huge sets
Materializes union. Expensive. Use SUNION + iterate.
Caching things that change
Cache without invalidation → stale data forever.
Ignoring cluster hash tags
Multi-key ops fail with CROSSSLOT. Use {tag}.
Per-call connections
Open + close per request → slow. Use pool.
Treating Redis as primary store without persistence
Restart = lost data.
Trusting client clock
ttl = expires_at - time.time() # client time
Drift between clients/server. Use server TTL (EXPIRE).
Storing large structured data without RedisJSON
Repeated parse + write of huge JSON strings.
Manual sharding without cluster
Roll your own keyhash → no rebalancing. Use Cluster.
Using lists for latest N without LTRIM
r.lpush("recent", item)
# missing: r.ltrim("recent", 0, 99)
Grows forever.
Ignoring slow commands
If SLOWLOG shows N seconds for SCAN, the COUNT is too high.
INCR for floats
Use INCRBYFLOAT.
TTL race
GET k
# expires here
SET ... with computed value
Use Lua for atomic.
Common mistakes
- Treating Redis as DB without persistence.
- Mixing cache + queue keys.
- No monitoring until production fire.
- Using Redis for things SQL is better at (relational queries).
- Premature cluster (single Redis fine to ~50GB).
Read this next
If you want my Redis review checklist, it’s at rajpoot.dev .
Building something AI-, backend-, or data-heavy and want a second pair of eyes? I do consulting and freelance work — see my projects and ways to reach me at rajpoot.dev .