The Silent Memory Killer: Why Your Redis Defaults Are Failing You in Production

It’s 3 AM, and your Kubernetes cluster is on fire. Half your pods are OOMKilled, memory usage is through the roof, and you’re frantically bumping Redis memory limits across dozens of microservices.
Again.
Here’s what took me way too long to figure out: Redis’s defaults are quietly killing your production systems.
Redis Works Great—Until It Doesn’t
Redis ships with sane defaults for development. No memory limits. No eviction policy. Data sticks around until you delete it.
Perfect on your laptop, where you’ve got one instance and a few kilobytes of test data.
But in production—especially on Kubernetes—it’s a disaster waiting to happen.
We’ve all done it: every microservice gets its own Redis instance via a Helm chart. Clean isolation. Easy to manage. Works great in staging.
Then production traffic hits… and suddenly you’ve got 20+ Redis pods, each chewing through memory independently, all on shared nodes.
No coordination. No limits. No cleanup.
The Real Problem: Your Libraries Are Memory Hogs
It’s not just Redis itself. It’s the libraries you’re using on top of Redis.
Most have defaults that are great for dev, terrible for prod.
express-session
stores sessions forever—unless you configure TTL.Sidekiq
keeps completed jobs indefinitely.Python’s
django.core.cache
? No default expiration.Session libraries across ecosystems often default to 2-week lifespans (or more).
These defaults feel safe during development. Losing a session is annoying. Storing everything "just in case" seems harmless.
Until your app hits production. And everything starts piling up.
I’ve seen:
Rails apps with 100MB+ of Sidekiq job data.
Node apps storing cached API responses from six months ago.
Python apps with every user session since launch still in memory.
Never mind JVM applications who don’t run the most recent version that support Redis TTL
The Fix: Make Redis Smarter About Memory
The solution isn't more memory. It's controlled memory.
Three things that will save you during your next on-call shift:
Set
maxmemory
.
Match your container limits—leave headroom.
If Redis has 512MB allocated, setmaxmemory
to 400MB.Use
allkeys-lru
.
The defaultnoeviction
will crash under pressure.
allkeys-lru
evicts least-recently-used data automatically.Accept that not all data matters equally.
Active sessions > stale cache.
Current jobs > completed ones.
LRU handles this without needing your app to be perfect.
CONFIG SET maxmemory 400mb
CONFIG SET maxmemory-policy allkeys-lru
Do this. Watch your memory plateau instead of climbing forever.
This Isn’t Just Redis
The bigger lesson?
Dev-friendly defaults almost never scale.
Your ORM may write fine queries in staging—then choke in prod.
Your log config might be silent locally—then flood disk in production.
Your cache might feel fast—because it never expires anything.
If it "just works" in development, it probably assumes small scale, short runtime, and no real traffic.
Before you ship, ask:
What happens when this runs for months, not minutes?
What happens at 10x traffic? 100x?
What breaks quietly before it breaks loud?
Because at 3 AM, when everything’s on fire, the line between developer convenience and operational pain becomes very real.
Set limits. Enable eviction. Plan for scale.
Your future self will thank you.
Subscribe to my newsletter
Read articles from Orchide Irakoze SR directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
