Feature Proposal: $releaseOnTimeout — Handle job timeout like a regular exception #59177
Unanswered
michaelgtfr
asked this question in
Ideas
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Problem
Currently, when a job times out, the Worker handles it via registerTimeoutHandler using a SIGALRM signal. This behavior differs significantly from how a regular exception is handled:
When a regular exception is thrown inside handle(), the Worker catches it, respects the configured backoff, and releases the job back onto the queue with the correct delay.
When a timeout occurs, the SIGALRM signal handler runs, dispatches a JobTimedOut event, and immediately kills the process via $this->kill(). Redis is never updated with the backoff delay — the job is only re-queued once the retry_after threshold is exceeded (90 seconds by default).
This means that even if a job defines a short backoff (e.g. 5 seconds), after a timeout it will not be retried until the retry_after delay has passed — which is inconsistent with the expected behavior and makes dynamic backoff configuration unreliable in timeout scenarios.
This issue has been raised previously in:
Proposed Solution
Laravel already provides $failOnTimeout to mark a job as permanently failed on timeout. I would like to propose a complementary attribute: $releaseOnTimeout.
When set to true, instead of letting the process be killed without updating Redis, the job would be released back onto the queue with its configured backoff — exactly like a regular exception would behave.
On the job:
In
Worker::registerTimeoutHandler():Why this approach
It is consistent with the existing $failOnTimeout attribute — same pattern, opposite behavior.
It is non-breaking — the default value is false, so existing jobs are unaffected.
It respects the configured backoff — the job is re-queued with the correct delay, just like after a regular exception.
It requires the retry_after to be set above the job's timeout (as already recommended in the Laravel documentation), which is the correct and expected configuration.
Notes
This does not conflict with $failOnTimeout. If $failOnTimeout = true and $releaseOnTimeout = true, markJobAsFailedIfItShouldFailOnTimeout() would mark the job as failed first, and the $job->hasFailed() check would prevent the release.
The small risk of kill() interrupting the Redis write from release() is inherent to the signal-based timeout mechanism and exists independently of this proposal.
I am happy to submit a PR if there is interest in this addition.
All reactions