The "Just Use Postgres" Trap

CodeOpinion (Derek Comartin)
CodeOpinion (Derek Comartin)Apr 22, 2026

Why It Matters

Choosing PostgreSQL over a dedicated broker can simplify infrastructure, but hidden queue semantics increase development risk; understanding the trade‑offs is essential for reliable, scalable systems.

Key Takeaways

  • Postgres can act as a queue, but adds custom semantics.
  • Queues require visibility timeout, retries, dead‑letter handling—features not built‑in.
  • Using FOR UPDATE SKIP LOCKED enables competing consumers in Postgres.
  • Polling frequency creates trade‑off between DB load and message latency.
  • Avoiding the outbox pattern is a key benefit of single‑store queues.

Summary

The video examines the growing advice to "just use Postgres" for all data needs, specifically as a message queue, and contrasts it with purpose‑built brokers like Kafka, Redis, and RabbitMQ. While a single database reduces infrastructure complexity, the presenter warns that queues are more than storage—they embody semantics such as visibility timeouts, retries, ordering, and dead‑letter handling that Postgres does not provide out of the box. Key insights include the need to implement queue semantics manually: a visibility timeout must be tracked, failed messages routed to dead‑letter tables, and back‑off logic added for retries. The speaker demonstrates a competing‑consumer pattern using a transaction with FOR UPDATE SKIP LOCKED, allowing multiple workers to lock and process rows concurrently. However, polling frequency introduces a trade‑off between database load and message latency, and solutions like LISTEN/NOTIFY only shift the burden to application code. Notable examples highlight that storing messages in the same PostgreSQL instance eliminates the classic outbox problem—state changes and message inserts can occur in a single transaction, guaranteeing atomicity. The presenter also cites practical considerations such as workload characteristics, retention requirements, and throughput limits, urging engineers to assess whether PostgreSQL can meet those demands or if a dedicated broker is warranted. The overall implication is that using PostgreSQL as a queue is viable for modest workloads when teams leverage existing SQL expertise, but it incurs an "implementation tax" of building and maintaining queue semantics. Architects should weigh the reduced operational overhead against the added code complexity, and consider mature messaging libraries that abstract these patterns if they choose this route.

Original Description

“Just use Postgres” is the modern architecture slogan. While simplifying your infrastructure sounds great, it doesn't always mean you've reduced complexity. Often, you’ve just relocated it. There is an "implementation tax" of using a relational database as a queue. While tools like Postgres, Kafka, and RabbitMQ might all store data, their semantics around retries, visibility timeouts, and concurrency are worlds apart.
🔗 Kurrent (formely EventStoreDB)
💥 Join this channel to get access to a private Discord Server and any source code in my videos.
🔥 Join via Patreon
✔️ Join via YouTube
0:00 Intro
2:37 Behaviors
3:50 Implementation
5:57 Concerns

Comments

Want to join the conversation?

Loading comments...