Skip to content

Re-lease delayed messages before RabbitMQ's consumer_timeout - #877

Open
davidt99 wants to merge 1 commit into
Bogdanp:masterfrom
intezer:rabbitmq-consumer-timeout
Open

Re-lease delayed messages before RabbitMQ's consumer_timeout#877
davidt99 wants to merge 1 commit into
Bogdanp:masterfrom
intezer:rabbitmq-consumer-timeout

Conversation

@davidt99

Copy link
Copy Markdown
Contributor

RabbitMQ requeues any delivery left unacked past its consumer_timeout (default 30 min, enforced since 3.8.15 on any queue type). Dramatiq holds delayed/retried messages unacked in memory until their eta, so a delay longer than the timeout is requeued by the server before it runs, churning the delay queue (#827).

Add an optional consumer_timeout to RabbitmqBroker. When set, it is sent as an x-consumer-timeout consumer argument on the delay-queue consumer only (honoured by RabbitMQ 3.12+), and the worker re-leases a held delayed message at 0.75x that value -- re-enqueuing it with its remaining delay so the eta is preserved and it still fires exactly once. Worker-side and queue-type agnostic; defaults to None (unchanged), minimum 15 minutes.

Addresses #827.

@davidt99

Copy link
Copy Markdown
Contributor Author

@LincolnPuzey as agreed, I'm only handling the consumer timeout. Although the behavior is relevant for rabbitmq, it exists on other potential brokers.
I think the free-thread build is flaky, the branch passed on my environment

@davidt99
davidt99 force-pushed the rabbitmq-consumer-timeout branch from bb1d947 to f56bf98 Compare July 15, 2026 11:04
RabbitMQ requeues any delivery left unacked past its consumer_timeout
(default 30 min, enforced since 3.8.15 on any queue type). Dramatiq holds
delayed/retried messages unacked in memory until their eta, so a delay
longer than the timeout is requeued by the server before it runs, churning
the delay queue (Bogdanp#827).

Add an optional consumer_timeout to RabbitmqBroker. When set, it is sent as
an x-consumer-timeout consumer argument on the delay-queue consumer only
(honoured by RabbitMQ 3.12+), and the worker re-leases a held delayed
message at 0.75x that value -- re-enqueuing it with its remaining delay so
the eta is preserved and it still fires exactly once. Worker-side and
queue-type agnostic; defaults to None (unchanged), minimum 15 minutes.

Addresses Bogdanp#827.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@davidt99
davidt99 force-pushed the rabbitmq-consumer-timeout branch from f56bf98 to 05a8f18 Compare July 23, 2026 11:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant