Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

nodkrot's avatar

Laravel Queue how to force retry?

I wasn't able to clearly find this in the docs so i had to manually experiment, this is how it behaves:

// ignores tries, backoff, and maxExceptions
$this->fail(new Exception('test'));

// respects tries, backoff, and maxExceptions
throw new Exception('test');

// respects tries and ignores backoff, maxExceptions
$this->release();

The use case that I needed but wasn't trivial is this, set

$backoff = [5, 10, 20]
$tries  = 10
$maxExceptions = 2

In handler code I want to force retry but I cannot do it because release will override backoff and throwing will be limited to maxException = 2. Am I missing something?

0 likes
8 replies
nodkrot's avatar

In certain condition in the job i want to retry with backoff and on exceptions only retry based on maxExceptions.

Glukinho's avatar

Can you describe more specific? Do you want your job to be retried immediately? Or without incrementing of attempts counter? Or what?

Do you realize that even if you return your job to queue and somehow set "no delay" the job is not neccessarily retried immediately? Queue worker can take other jobs prior to yours. In general, queue worker doesn't guarantee a job is executed at exact time, it just takes jobs one by one, taking into account delay/backoff/max attempts you set.

Maybe you should retry an action you want to be retried in a job by yourself, inside a job?

Or tell more about your scenario, maybe there is another solution.

Snapey's avatar

I imagined they might be calling an api. If the api does not respond, then retry it using the backoff pattern, for up to 10 times. But if the api replies with an invalid response, don't keep retrying. Give it another shot and then kill the job.

Glukinho's avatar

@snapey In this case I'd use HTTP client retries functionality Http::retry(...) instead of retrying a job: https://laravel.com/docs/12.x/http-client#retries

Here is exactly what you described:

If needed, you may pass a third argument to the retry method. The third argument should be a callable that determines if the retries should actually be attempted. For example, you may wish to only retry the request if the initial request encounters an ConnectionException:

$response = Http::retry(3, 100, function (Exception $exception, PendingRequest $request) {
    return $exception instanceof ConnectionException;
})->post(/* ... */);
Snapey's avatar

I'd be interested to know if the worker is released during this backoff. I doubt it.

nodkrot's avatar

The job makes external API calls, when we get a 429 we want to retry with backoffs specified in the array. If we get other exceptions we want to retry maxException number of times.

Currently we ended up throwing on 429 so it retries with backoffs, and failing the job on other exceptions (basically we cannot use maxExceptions). This is fine but I thought it was strange that i couldn't programmatically release the job so that it retries and respects backoffs.

Please or to participate in this conversation.