I Thought Redis Was Just a Cache. I Was Wrong.
If someone had asked me a year ago,
"What is Redis?"
My answer would've been something like:
"It's a fast cache."
Technically...
Not wrong.
But also nowhere close to the full story.
Building my notification system completely changed how I looked at Redis.
Turns out, Redis spends most of its day doing things that have nothing to do with caching.
My original plan
My architecture looked like this.
API
↓
Kafka
↓
Consumer
↓
PostgreSQL
Simple.
Kafka handled asynchronous processing.
PostgreSQL stored notifications.
Everything looked good.
Then reality showed up.
Problem ##1 — Duplicate notifications
Kafka guarantees at-least-once delivery.
That's great.
Because it means messages aren't silently lost.
The downside?
Sometimes they're delivered...
again.
Imagine this happens.
Consumer receives message
↓
Saves to database
↓
Application crashes
↓
Kafka retries
Now the exact same notification arrives again.
Without protection...
Your user gets
"You have a new message."
Twice.
Which is technically true.
But still annoying.
Redis to the rescue
Every notification in my system gets a unique eventId.
Before processing anything, the consumer asks Redis
Have I already processed this event?
If Redis says
Yes
The consumer simply ignores it.
If Redis says
No
The notification gets processed and Redis remembers that ID for a while.
Problem solved.
No duplicate notifications.
No complicated database queries.
Just one very fast lookup.
Wait...
Why not PostgreSQL?
That was my first thought too.
I could have stored every processed ID in PostgreSQL.
It would've worked.
But imagine asking a database thousands of times per second
"Have you seen this UUID?"
Databases can absolutely do that.
Redis just does it much faster.
It's basically the difference between asking your friend
"Do you remember this?"
and asking someone with perfect photographic memory.
Then Redis got another job
While I already had Redis running...
I realized it could also handle rate limiting.
Suppose one user suddenly decides to send
10,000 notifications
in a few seconds.
Not ideal.
So before accepting a request, I increment a Redis counter.
user:123
↓
INCR
↓
7 requests
If the count exceeds the configured limit...
HTTP 429
Too Many Requests
No complicated scheduler.
No background cleanup.
Redis automatically removes expired keys.
It quietly cleans up after itself.
If only my room worked that way.
Redis isn't trying to replace your database
This was another thing I misunderstood.
Redis and PostgreSQL aren't competitors.
They have completely different jobs.
PostgreSQL
↓
Permanent storage
Reliable
Durable
Queries
Redis
↓
Temporary memory
Extremely fast
Simple lookups
Counters
Locks
Queues
One remembers things forever.
The other remembers them just long enough.
They're teammates.
Not rivals.
So... is Redis just a cache?
After this project?
Definitely not.
For me Redis became:
- A duplicate detector
- A rate limiter
- A temporary memory store
- A performance booster
And yes...
Sometimes it's still just a cache.
Things I learned
Building this project taught me that Redis is one of those tools that keeps finding new jobs.
You start by using it as a cache.
A few weeks later it's also handling:
- Sessions
- Rate limiting
- Idempotency
- Distributed locks
- Pub/Sub
- Leaderboards
It's basically the backend equivalent of that coworker who somehow ends up fixing everyone's problems.
Final thoughts
The biggest lesson wasn't that Redis is fast.
Everyone already knows that.
The interesting part was learning why people choose Redis.
Not because databases are bad.
But because some problems don't need permanent storage.
They just need someone who can answer
"Have we seen this before?"
in less than a millisecond.
Redis is surprisingly good at that.