Contents

Backend Development › Queues & Async Processing

Visibility Timeout

How long a received message stays hidden before it's delivered again.

Also known as: visibility timeout, message visibility, in-flight timeout

A visibility timeout is the period after a consumer receives a message during which it’s hidden from other consumers. If the consumer acknowledges the message within the window, it’s deleted; if the window expires first (because the consumer crashed or is too slow), the message becomes visible again and another consumer can take it.

consume message → hidden for N seconds → ack? delete : reappear for redelivery

It’s the queue’s mechanism for recovering from failed consumers: a message that was handed out but never completed comes back. It’s central to how at-least-once delivery works on queues that don’t track per-consumer state.

The classic mistakes:

  • Timeout shorter than processing time. A slow job exceeds the window, the message reappears, and another consumer processes it while the first is still working — duplicate processing, often concurrently. Make handlers idempotent (see idempotence) and set the timeout above worst-case time.
  • Timeout too long. A crashed consumer’s message stays hidden for the full window, delaying recovery. Balance: long enough for real work, short enough to retry promptly.
  • Processing that can’t extend the timeout. For long jobs, some queues let a worker “heartbeat”/extend the visibility while working; without it, long jobs are redelivered and duplicated. Use the extension mechanism if available.
  • Assuming exactly-once because it’s hidden. Hiding prevents concurrent delivery during the window but doesn’t guarantee single processing — a timeout after partial work means a duplicate. Assume at-least-once.
  • No dead-lettering after repeated timeouts. A message that always times out (a poison message) keeps reappearing; after a bounded number of attempts, send it to a dead-letter queue.
  • Forgetting the poison-message case. Poison messages may fail or time out forever; the timeout alone won’t clear them (see poison message).

How to set it: pick a timeout comfortably above the p99 processing time (plus margin), make consumers idempotent, extend the visibility for genuinely long jobs if the broker allows, and dead-letter after a bounded retry count. It’s the queue’s safety net for lost consumers — tuned wrong, it creates duplicates or slow recovery. See acknowledgement.