check out these videos regarding the queue configuration options
https://divinglaravel.com/explaining-laravel-queue-configuration-keys
I'm sure your answer is in one of the short videos from mohamed said
Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.
I have a queue job that may fail due to the receiving API being down (part of the job is to send data to an external API), this has not happen yet but it has happened in the past before using laravel, is there a way to re-try the job if it fails but only after say 2-3 minutes? I know I can specify the number of tries but I think they get tried one after another, thanks!
check out these videos regarding the queue configuration options
https://divinglaravel.com/explaining-laravel-queue-configuration-keys
I'm sure your answer is in one of the short videos from mohamed said
Awesome thanks!
Please mark as answered if you find the solution
@man-u-l
failed_jobs table by Laravel$this->laravel['queue.failer']->all();, see vendor\laravel\framework\src\Illuminate\Queue\Console\ListFailedCommand.php
Artisan::call('queue:retry $id');, or php artisan queue:retry
Artisan::call('queue:retry all'), but I don't recommend it$scheduler
You can combine ->attempts() and ->release() from the InteractsWithQueue trait:
<?php
namespace App\Jobs;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
class SampleJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
// override the queue tries
// configuration for this job
public $tries = 4;
public function __construct()
{
//
}
public function handle()
{
try {
// make api call
} catch (\Throwable $exception) {
if ($this->attempts() > 3) {
// hard fail after 3 attempts
throw $exception;
}
// requeue this job to be executes
// in 3 minutes (180 seconds) from now
$this->release(180);
return;
}
}
}
->release() will send the job back to queue, you can specify a delay in seconds. If you release the job without failing it will be sent back to queue instead of sending to the failed_jobs table.
->attempts() will give you how many times this job has been attempted before. In the example above, after 3 unsuccessful attempts we hard fail the job (re-throw the caught exception) so it is sent to the failed_jobs table.
There are other configurations such as retryUntil, and Laravel 8 introduces the backoff property where you can specify exponential delays between new attempts.
Thanks a lot for all the help, I have added to my job the following:
public $tries = 5;
public $retryAfter = 5 * 60;
What I want is to wait 5 minutes after each attempt and try again hoping the API will be back up by then, otherwise try every 5 minutes until 5 tries are over for a total of 25 minutes or so, now if that happens I will like to try again after 3 hours rather than coming back to try the jobs manually again, for that I will do:
$this->release( 3 * 3600);
This last part Im not sure if it will work... maybe @rodrigo.pedra can tell me if it will.
The problem here is that the API in the past has been down for more than 3 hours, what I did in my old system was to have a script that updated a json document the script checked every minute if the API was up and if it was not the JSON document will be updated, then my old system will not attempt any jobs till the API was up, but now I am moving to Laravel and the jobs work a little different.
I guess this question has now been answered, I will mark it as such and ask a new question about how to not perform a Job till a criteria is met (json document saids API is up)
@man-u-l
http://snags88.github.io/backoff-strategy-for-laravel-jobs
This should suit your logic
if ($this->currentRetryCount <= 5) $this->delay(now()->addSeconds(5 * 60));
if ($this->currentRetryCount > 5) $this->delay(now()->addSeconds(3 * 3600));
here is an example combining retryUntil and backoff (available starting at Laravel 8):
<?php
namespace App\Jobs;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
class SampleJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public function __construct()
{
//
}
public function handle()
{
try {
// make api call
} catch (\Throwable $exception) {
if ($this->attempts() > 9) {
// hard fail after 9 attempts
throw $exception;
}
// requeue this job to be executes
// in 3 minutes (180 seconds) from now
$this->release(180);
return;
}
}
public function retryUntil()
{
// will keep retrying, by backoff logic below
// until 12 hours from first run.
// After that, if it fails it will go
// to the failed_jobs table
return now()->addHours(12);
}
/**
* Calculate the number of seconds to wait before retrying the job.
*
* @return array
*/
public function backoff()
{
// first 5 retries, after first failure
// will be 5 minutes (300 seconds) apart,
// further attempts will be
// 3 hours (10,800 seconds) after
// previous attempt
return [300, 300, 300, 300, 300, 10800];
}
}
References:
https://laravel.com/docs/8.x/queues#time-based-attempts
https://laravel.com/docs/8.x/queues#dealing-with-failed-jobs
Thanks @rodrigo.pedra
For my second question I think I will include some logic in my check API script and if the API is down then the queue for this job will be stoped and once the API is back up I will restart the queue, this way I dont have a bunch of jobs trying to execute while I already know they will not succeed, I will still implement the retry and wait times just in case, but that should now happen if first I am checking that the API is up or not.
What do you think if this approach?
What I am finding out is that stopping a queue is not as easy as starting it, for starting a specific queue I run:
php artisan queue:work redis --queue=queue-name
But for stopping it I will need to do some research
If the process is not being run in background it should be as easy as stopping the process.
You can try running;
php artisan queue:restart
This will tell the queue to restart after processing the current job. If your queues are not kept running by supervisor or other mechanism they should be stopped.
I am not sure if you need to use the queue name as a parameter to that command, I am not in my computer right now to check
Please or to participate in this conversation.