Background Job Queues: The Architecture Decision Founders Skip
A background job queue is the system that runs work asynchronously from the user request. It is the right place for sending email, processing files, calling external APIs, generating reports, and anything that should not block the response. The queue choice determines the failure model, the retry semantics, the observability story, and the operational tax of the product for years. Most founders pick by accident. The ones who pick by design save quarters of work.
Written by Yashveer Singh, founder of Yashveer Labs.
What you actually need to know
- Almost every SaaS needs a background queue from day one.
- Postgres backed queues are the right starting point for most teams.
- Move to Redis based or dedicated queues when scale demands.
- Workflow engines are a different tool for multi step processes.
- Idempotency, retries, and dead letter handling are non negotiable.
| Queue option | Best fit | Scale ceiling | Operational tax |
|---|---|---|---|
| Postgres queue (Graphile, River, pg-boss) | Most early SaaS | 5k to 10k jobs per minute | Negligible |
| Redis queue (BullMQ, Sidekiq) | Growing SaaS | 50k to 100k jobs per minute | Low |
| SQS or RabbitMQ | High scale or specific routing needs | Hundreds of thousands per minute | Medium |
| Inngest, Trigger.dev | Teams that want managed | Vendor scales | Lowest |
| Temporal, Step Functions | Multi step workflows | High | Higher operational overhead |
The core argument
Every SaaS I have rescued had a queue problem. The pattern is consistent. The team did not pick a queue. They picked the first thing that worked. The first thing that worked was usually a setTimeout, a hand rolled cron, or a Sidekiq install with no monitoring. The product worked at small scale. At meaningful scale, the queue became the source of incidents.
The right queue is the one that matches the workload, the team size, and the operational appetite. A team of two engineers should not be running Kafka for background jobs. A team of fifty engineers should not be running a single Postgres table. The choice changes as the product grows.
The mistake is treating the queue as a low value decision. The queue is one of the three or four architectural choices that compound. Get it right and the product grows quietly. Get it wrong and the team spends a year unwinding the choice while the product stalls.
The good news is that the modern landscape has good defaults. For most early stage SaaS, a Postgres backed queue is the right call. The operational tax is near zero. The scale is sufficient for the first few thousand customers. The migration path to something heavier is well understood.
Picking the right queue for the workload
Three workload shapes. Steady state low volume. Bursty high volume. Long running stateful.
Steady state low volume is the easy case. A few hundred jobs per minute, predictable. Almost any queue works. Pick the one that integrates cleanly with your stack.
Bursty high volume is where the queue choice matters. The queue has to absorb the burst without dropping jobs and process them as fast as the worker pool allows. Redis based queues handle this well. Postgres based queues hit limits earlier.
Long running stateful is the workflow engine case. A job that runs across multiple steps over hours or days, with retries per step and the ability to resume after a worker restart. Temporal, Inngest, and Step Functions are the right tools. A simple queue is the wrong tool.
How much does this cost
| Option | Engineering setup | Monthly cost at modest scale | Notes |
|---|---|---|---|
| Postgres queue | A few hours | Negligible | Runs on your existing database |
| Redis queue | Half a day | 50 to 200 USD for Redis | Add Redis to the stack |
| SQS | Half a day | Under 50 USD | AWS specific |
| Inngest | Half a day | Free to 200 USD | Managed |
| Trigger.dev | Half a day | Free to 200 USD | Managed |
| Temporal Cloud | One to two days | Higher | Workflow engine |
Features the queue must have
- Idempotent job design as a first class concern.
- Exponential backoff with maximum retry count.
- Dead letter destination for terminal failures.
- Observability for queue depth, throughput, failure rate, and latency.
- Schedule support for cron style jobs.
- Worker concurrency control to prevent resource exhaustion.
- A clear path from development to production.
Expert opinion
The queue is the part of the system that runs in the dark. It does not have a UI. It does not have a request log. It does not surface its failures unless you wire them up. The teams that take the queue seriously from day one get a quiet, reliable layer. The teams that treat it as an afterthought get the loudest incidents of their year.
>
Yashveer Singh, founder of Yashveer Labs
How this played out on a real project
A SaaS client had been running their background work on a hand rolled cron loop that processed a database table. The system worked for the first three thousand customers. At seven thousand customers the cron loop was missing windows and producing duplicate work. The team had spent six weeks trying to patch it.
We migrated to a Postgres backed queue with idempotent jobs and exponential backoff retries. The migration took eight working days. The queue depth dropped from a backlog of hundreds of thousands of stuck jobs to a steady state of under a thousand. The duplicate work stopped.
Eighteen months later, at thirty thousand customers, we migrated the highest volume job class to a Redis queue. The migration was contained because the abstraction over the queue had been built correctly the first time. The team did not have to rewrite job logic.
For more on the related architecture work, see the outbox pattern a SaaS reliability cheat code and async job failure recovery patterns that actually work.
Common mistakes teams make
- No queue at all. Long running work in the request thread.
- Hand rolled cron loops over a database table.
- Jobs that are not idempotent. Retries duplicate side effects.
- No dead letter handling. Failed jobs disappear into the void.
- No observability. The queue is a black box.
- Mixing job priorities in one queue. A low priority job blocks a high priority one.
- Treating the queue as the workflow engine. Multi step state belongs elsewhere.
- Picking Kafka for background jobs. Wrong tool for the workload.
A two week plan to put a queue in place
- Day one. Inventory the candidate background work. Email, webhooks, exports, scheduled tasks.
- Days two and three. Pick the queue. Postgres backed for most early SaaS.
- Days four to six. Migrate the first job. Send the welcome email through the queue.
- Days seven to nine. Migrate the rest. Make every job idempotent.
- Day ten. Wire observability. Queue depth, throughput, failure rate.
- Days eleven and twelve. Set up alerts. Define the runbook.
- Days thirteen and fourteen. Load test. Confirm the queue handles the expected burst.
For more on the related infrastructure work, read background jobs at scale Inngest Trigger Cron and beyond and workflow engines when you need Temporal when you need Cron. On the reliability side, why your SaaS should have a job queue from day one is the natural next read.
Frequently asked
The engineer behind this page
This was written by Yashveer Singh. Full stack developer, founder of Yashveer Labs, currently in Class 12 in New Delhi, shipping production systems while most of my peers are still writing their first console app. I am pointing the work, on purpose, at machine learning, AI engineering, and cybersecurity. If you are reading this because you want to hire someone who will not waste your time or your money, that is the role I am built for.
Posts that line up with this one.
- SaaS Architecture and Scaling
The Background Sync Problem: Patterns That Survive
The background sync patterns that keep SaaS data consistent without blocking the user or corrupting the state. What works, what breaks, and when each applies.
- SaaS Architecture and Scaling
Tenant Isolation: How Much Is Enough for B2B Customers
B2B customers want their data separated from other customers. Here is how to think about the right level of tenant isolation for your SaaS product.
- SaaS Architecture and Scaling
The Compliance Dashboard: A SaaS Asset Worth Building Internally
A compliance dashboard surfaces security and regulatory status in real time. Here is why it is worth building internally and what it should include.
- SaaS Architecture and Scaling
Idempotency in API Design: Why It Matters More Than You Think
An idempotent API is one that handles repeated requests gracefully. Building it in from the start is far cheaper than retrofitting it after your first double-charge incident.