System Design

Message Queues

Decouple producers and consumers so the system can smooth spikes, retry work safely, and move slow tasks out of the request path.

async-processingdurabilitybackground-jobs
Published: Mar 31, 2026

Why Queues Matter

Some work should not happen inside the main request-response path.

Examples include:

  • sending emails
  • generating thumbnails
  • processing analytics events
  • syncing data with third-party services

Queues let you accept the request quickly and process the expensive or slow work later.

Producer And Consumer Model

A producer publishes a message. One or more consumers pull messages and process them.

That separation helps with:

  • absorbing traffic spikes
  • retrying transient failures
  • scaling workers independently of the API layer

Message Flow

Diagram
flowchart LR API[API Service] --> Queue[(Message Queue)] Queue --> Worker1[Worker 1] Queue --> Worker2[Worker 2] Worker1 --> DB[(Database)] Worker2 --> DB
visualized byIOCombats

Important Design Concerns

Delivery Semantics

Understand whether the queue is at-most-once, at-least-once, or exactly-once in practice.

Most real systems assume retries can happen and make consumers idempotent.

Dead Letter Queues

When a message keeps failing, move it aside instead of retrying forever.

Backpressure

If producers generate faster than consumers can process, queue depth grows. That is useful as a buffer, but it is also a signal that the system is falling behind.

When A Queue Helps Most

  • user response time matters more than immediate completion
  • failures in downstream systems should not block requests
  • traffic arrives in bursts
  • work can be retried safely

Design Checklist

  • Is the job idempotent?
  • How will retries be limited?
  • What metrics reveal consumer lag?
  • When does the queue become too backed up to be acceptable?
Frequently Asked Questions

When should I use a queue instead of a direct call?

Use a queue when the work can be processed asynchronously, when you need buffering during spikes, or when producer and consumer lifecycles should be decoupled.

Does a queue guarantee no duplicate processing?

Not automatically. Many queue systems deliver at least once, so consumers should be idempotent and safe to retry.