Filter concepts by levelShowing all levels.

System Design · Messaging and Queues

Messaging and Queues

Blocking vs handing off, the delivery vocabulary, and what a queue actually buys a design

  • Sync vs asyncwait for a result vs hand off and continue
  • Queue vocabularyproducer, broker, consumer, ack, DLQ
  • Decouplingindependent scaling, failure, deploys
  • Burst absorptiondrain at a sustainable rate

1.Synchronous request/response vs asynchronous messaging

Synchronous request/response means the caller waits for the callee to finish and reply before continuing — simple, but the caller is blocked for as long as the work takes, and a slow or down dependency directly slows or breaks the caller. Asynchronous messaging means the caller hands off a message and continues immediately, with the work happening independently — the caller is decoupled from how long the work takes, at the cost of not having an immediate result.

Key features

  • Synchronous: caller blocks until the response arrives — simple mental model, direct coupling to the callee's latency and availability
  • Asynchronous: caller sends a message and continues without waiting for the work to finish — decouples the caller's response time from the work's duration
  • Synchronous is the natural fit when the caller genuinely needs a result before it can proceed (a login check, a price lookup for checkout)
  • Asynchronous is the natural fit for work that doesn't need to complete before the caller's request finishes (sending an email, generating a report, updating a search index)
  • Choosing synchronous when the work is slow or unreliable directly transfers that slowness/unreliability to every caller

Synchronous vs asynchronous, at a glance

Synchronous vs asynchronous, at a glance
PropertySynchronousAsynchronous
Caller waits?Yes, for the full durationNo, hands off and continues
Coupling to callee's latencyDirect — caller is only as fast as the calleeDecoupled — caller's response time is independent
Failure propagationA callee failure is immediately visible to the callerFailure can be retried/handled without the caller ever knowing
Good fitWork the caller needs a result from right nowWork that can happen after the caller's request completes
Signup: synchronous vs asynchronous email

Synchronous

  • Server waits for the email provider to confirm
  • A slow or down provider slows or breaks every signup
  • Caller is blocked for the full duration

Asynchronous

  • Server publishes to a queue and returns immediately
  • A worker sends the email independently, whenever it can
  • Signup succeeds regardless of the email provider's speed
  • Synchronous
    • Server waits for the email provider to confirm
    • A slow or down provider slows or breaks every signup
    • Caller is blocked for the full duration
  • Asynchronous
    • Server publishes to a queue and returns immediately
    • A worker sends the email independently, whenever it can
    • Signup succeeds regardless of the email provider's speed

Command

text
sync:  client -> service -> [wait] -> response -> client
async: client -> queue -> [continue immediately]
                    ↓
                 worker -> processes later

Synchronous: caller waits, simple, but directly coupled to the callee's speed and availability. Asynchronous: caller continues immediately, decoupled, but has no immediate result — use it for work the caller does not need a result from before proceeding.

2.The queue vocabulary: producer, consumer, broker and the delivery mechanics

These nine terms describe every part of how a message gets from a producer to being successfully processed. A producer sends messages; a broker stores and routes them; a consumer reads and processes them. The remaining terms describe the mechanics of reliable delivery: how a broker tracks position (partition, offset), how a consumer confirms success (acknowledgement, visibility timeout), and what happens on failure (retry, dead-letter queue).

Key features

  • Producer, consumer, broker: the producer sends messages, the broker (RabbitMQ, Kafka, SQS) stores and routes them durably, the consumer reads and processes them
  • Partition and offset: a broker may split a queue/topic into partitions for parallelism, each preserving order independently; offset is a consumer's read position within a partition
  • Acknowledgement (ack): a consumer's explicit signal that a message was processed successfully and can be removed/marked done
  • Visibility timeout: after delivery, the broker hides a message from other consumers for this window — if no ack arrives before it expires, the message becomes visible again for redelivery
  • Retry: reprocessing a message that failed or was not acknowledged in time, usually with a limited number of attempts
  • Dead-letter queue (DLQ): a separate queue a message is moved to after exceeding its retry limit, so it doesn't block the main queue forever and can be inspected manually

The nine terms, grouped by role

The nine terms, grouped by role
TermRole
ProducerSends messages
ConsumerReads and processes messages
BrokerStores and routes messages between the two
PartitionA subdivision of a queue/topic for parallel processing
OffsetA consumer's read position within a partition
AcknowledgementConsumer's confirmation that a message was handled
Visibility timeoutHow long a message stays hidden after delivery, before becoming re-deliverable
RetryReprocessing a failed or un-acked message
Dead-letter queueWhere a message goes after exhausting its retries
A message's lifecycle through the queue
senddeliveracktimeout,max retries

Producer

sends the message

Broker

stores at an offset

Consumer

visibility timeout starts

Acked

removed, done

Dead-letter queue

after max retries

  • Producer — sends the message
    • leads to Broker (send)
  • Broker — stores at an offset
    • leads to Consumer (deliver)
  • Consumer — visibility timeout starts
    • leads to Acked (ack)
    • on error, leads to Dead-letter queue (timeout, max retries)
  • Acked — removed, done
  • Dead-letter queue — after max retries

Command

text
producer → broker (partition 0..N, tracked by offset)
                ↓
             consumer receives, gets a visibility timeout
                ↓
        ack (success, remove) | timeout expires → redeliver
                ↓ (after max retries)
           dead-letter queue

Producer sends, broker stores/routes, consumer reads. Offset tracks position within a partition. Ack confirms success; visibility timeout governs redelivery on silence; retries are bounded, with a dead-letter queue catching what exceeds the limit.

3.Using queues to decouple services, absorb bursts and move slow work off the request path

A queue between two components solves three related problems at once: it lets the producer and consumer scale, fail and deploy independently (decoupling), it lets a burst of incoming work be absorbed and processed at a steady rate rather than overwhelming a downstream service (buffering), and it lets slow, non-critical work happen after a request has already returned to the caller (moving work off the critical path).

Key features

  • Decoupling: producer and consumer don't need to be online, healthy or the same speed at the same moment — the queue absorbs the gap
  • Burst absorption: a queue lets a spike of incoming work be processed at the consumer's sustainable rate instead of forcing the consumer to handle the peak instantly
  • Moving work off the request path: slow, non-critical work (sending notifications, generating reports, reindexing search) can happen after the request already returned
  • Independent scaling: producers and consumers can each scale based on their own load, not tied to each other's instance count
  • The trade-off: a queue adds latency for the queued work (it no longer happens instantly) and a new failure mode (queue backlog) that needs its own monitoring

Three problems a queue solves, with a concrete example each

Three problems a queue solves, with a concrete example each
ProblemWithout a queueWith a queue
DecouplingProducer fails/slows if the consumer is downProducer keeps working; messages wait for the consumer to recover
Burst absorptionA traffic spike directly overloads the downstream serviceThe spike queues up; the consumer drains it at a sustainable rate
Off request pathA slow step (email, PDF generation) blocks the responseThe response returns immediately; a worker handles the slow step after
A queue absorbing a burst
enqueuesustainablerate

Uploads

200/sec burst

Queue

buffers the burst

Workers

drain at 50/sec

  • Uploads — 200/sec burst
    • leads to Queue (enqueue)
  • Queue — buffers the burst
    • leads to Workers (sustainable rate)
  • Workers — drain at 50/sec

Signature

queues: decouple producer/consumer, absorb bursts, move slow work off the request path

A queue decouples producer from consumer, absorbs bursts by letting the consumer drain at its own sustainable rate, and moves slow non-critical work off the request path — but it only buys time, so consumer capacity still has to scale to match sustained (not just momentary) load.

Remember

  • Synchronous is for work the caller genuinely needs a result from before proceeding — everything else is a queuing candidate.
  • A visibility timeout shorter than real processing time causes self-inflicted duplicate delivery.
  • A dead-letter queue keeps one permanently-failing message from blocking or endlessly retrying.
  • A queue buys time to catch up — consumer capacity still has to scale for sustained (not just momentary) load.

Pro tip

  • Move slow, non-critical side effects (email, indexing, reports) off the request path by default.
  • Autoscale consumers on queue depth or message age, not a fixed instance count.

Next up

  • Kafka and log-based messaging
  • RabbitMQ and traditional message brokers
  • Delivery semantics and idempotency

Sources

  • AWS SQS documentation — docs.aws.amazon.com
  • System Design Primer — github.com/donnemartin/system-design-primer
  • Checked 2026-08-21

Spotted a mistake on this page? Tell us.