Architecture Note: When to pick SQS FIFO over a DB queue
A decision framework I use when the team reaches for a Postgres-backed queue by default.
Part of Backend Craft
Teams reach for "just use a table" queues more than they should. Sometimes that's right. Often it's a time bomb.
My decision tree:
- Is ordering per-key required? → SQS FIFO with MessageGroupId. A DB queue gets this right only if you're careful with
SELECT FOR UPDATE SKIP LOCKED. - Is throughput ever going to exceed a few hundred/sec? → SQS. DB queues fight with the rest of your app for connections and row locks.
- Is exactly-once needed at the consumer? → Neither gives you that. Design idempotent consumers; use SQS FIFO's dedup window as a safety net.
- Is the consumer outside the DB's blast radius? → SQS. Don't couple an external worker to your primary Postgres.
A DB queue is right when the work is intrinsically tied to a transaction — "after this row commits, do X." SQS is right when the work is extrinsic.
Written by
Adrian Romo
Senior Backend Engineer building scalable Python APIs, AWS Lambda architectures, voice systems, and enterprise integrations.
Related
Keep reading
Assembled Primitives vs. a Platform
I built a voice agent out of cloud primitives, and it worked. It has since been replaced by a purpose-built voice platform, and I think that was the right call.
Six Posts a Day, and the Scheduler That Learned to Say When
A social pipeline that published one Reel a day and nothing else, because per-format quotas were ceilings and nothing was asking for the other formats.
A Planner That Will Not Onboard Anything
The tool that decides how to onboard a new service into my homelab has no ability to onboard a service. That separation is the design, not a limitation.
Keep going
Where to next?
Browse more technical writing, see the engineering case studies, or reach out directly.