Queues, background jobs and pub/sub
Some work is too slow, too big or too fragile to do while the user waits. A queue lets the API say "got it" in milliseconds and hands the work to background workers. This lesson shows how that works, how jobs fail and retry safely, and how to pick a tool.
By the end you can
- Decide which work must happen in the request and which can move to a queue
- Explain at-least-once delivery and write an idempotent consumer
- Configure retries with exponential backoff and handle a dead-letter queue
- Tell a queue, pub/sub and a log (Kafka) apart
- Build a BullMQ producer and worker in NestJS, and a Postgres queue with
SKIP LOCKED
The everyday picture
At a busy takeaway restaurant, the person at the counter takes your order, prints a ticket, gives you a token number, and turns to the next customer. It takes thirty seconds. The ticket goes onto a rail in the kitchen, and the cooks take tickets one by one at their own pace. When it is busy, the rail gets longer, but the counter keeps moving.
If a cook burns a dish, he makes it again. If an order is impossible (the item is finished for the day), the ticket goes to the manager instead of being cooked forever. And if the kitchen falls behind badly, the manager stops taking orders for a while. Those are the four ideas of this lesson: a fast acceptance, a queue, workers that retry, and a plan for jobs that never succeed.
Sync or async: what must happen before you reply?
Synchronous work happens inside the request: the user waits until it is done. Asynchronous work is accepted now and finished later. For each step of a feature, ask: does the user need the result of this step to continue?
Saving a sale: yes, the cashier must know it is recorded. Sending the e-receipt SMS, updating the loyalty dashboard, building a 200,000-row Excel export, resizing the product photo (Files, object storage and CDNs): no. Those are good queue candidates, especially when they are slow (more than about a second), heavy on CPU or memory, or depend on an outside service that can be slow or down.
For long work, the API answers 202 Accepted with a job id. The client then checks a status endpoint, or gets told when it is done (Real-time updates). The request takes milliseconds no matter how long the work takes, and a load balancer timeout can no longer kill it (Load balancers).
Quick check
A customer places an order in the Mangrove app. Which step should finish before the API replies?
The customer needs to know the order exists and the stock is held, so that work stays in the request. The SMS and the dashboard can follow a few seconds later from a queue, and a slow SMS gateway should never make checkout slow.