Short answer: Use PostgreSQL as your durable source of truth for relational data, Redis as a fast in-memory cache (and for sessions, rate limiting, and ephemeral data), and RabbitMQ as a message broker for asynchronous communication between services. They aren't competitors — a solid backend often uses all three, each for the job it's best at.
What role does each one play?
These three tools get lumped together, but they solve completely different problems:
- PostgreSQL — a relational database and your system of record: durable, transactional, queryable data.
- Redis — an in-memory data store for speed: caching, sessions, counters, rate limits, and short-lived data.
- RabbitMQ — a message broker for asynchronous, decoupled communication between services.
At a glance
| Tool | Type | Reach for it when… |
|---|---|---|
| PostgreSQL | Relational database | You need durable, consistent, queryable data (users, orders, records) |
| Redis | In-memory store | You need speed: caching, sessions, rate limiting, ephemeral data |
| RabbitMQ | Message broker | Services need to talk asynchronously without waiting on each other |
When should you use PostgreSQL?
PostgreSQL is the default home for data that must not be lost and must stay consistent — user accounts, orders, transactions, relationships between entities. You get ACID transactions, foreign keys, rich querying, and a mature ecosystem. If a piece of data is the "truth" your app relies on, it belongs in PostgreSQL (or another relational database). Everything else in this article sits around that source of truth.
When should you use Redis?
Reach for Redis when speed is the problem. Because it holds data in memory, reads are extremely fast — so it shines for:
- Caching — store the result of an expensive query or API call so you don't recompute it on every request.
- Sessions — fast, shared session storage across instances.
- Rate limiting — cheap per-user counters with expiry.
- Ephemeral data — anything short-lived that doesn't need durable storage.
The key mental model: Redis sits in front of PostgreSQL, not instead of it. It's a speed layer, not the source of truth — treat its data as disposable.
When should you use RabbitMQ?
Use RabbitMQ when one part of your system needs to tell another that something happened, without waiting for a reply. Instead of Service A calling Service B directly over HTTP and blocking until it responds, Service A publishes a message and moves on; Service B consumes it on its own schedule.
That asynchronous, decoupled approach buys you three things: resilience (if a consumer is down, messages wait in the queue instead of failing), loose coupling (services only agree on message formats, not each other's APIs), and load smoothing (spikes are absorbed by the queue). I lean on this pattern heavily in microservices architectures.
Redis vs RabbitMQ — aren't they both queues?
This is the most common point of confusion. Redis can do simple pub/sub and lists, so people use it as a lightweight queue. But RabbitMQ is a purpose-built broker with delivery guarantees, acknowledgements, retries, dead-letter queues, and flexible routing. If losing a message is acceptable and you want something quick, Redis pub/sub is fine. If messages must be delivered and processed reliably (payments, orders, inventory), use RabbitMQ. Different guarantees, different jobs.
How they work together
Picture an order in an e-commerce backend:
- The order is written to PostgreSQL — the durable source of truth.
- The product catalog the checkout page reads is served from Redis cache, so it stays fast under load.
- Once the order is confirmed, the service publishes an event to RabbitMQ; the inventory and notification services consume it and update stock and email the customer independently.
Each tool does one job well, and together they give you a backend that's durable, fast, and resilient.
Conclusion
PostgreSQL, Redis, and RabbitMQ aren't alternatives to choose between — they're complementary layers. Store your truth in PostgreSQL, make it fast with Redis, and decouple your services with RabbitMQ. Add each one when it solves a real problem, not by default, and you'll have a backend that scales cleanly.
Curious how this fits into a larger system? See how I structure a polyglot microservices architecture.








