Prevent Duplicate Jobs in Laravel with ShouldBeUnique
Imagine your application dispatches a job whenever a report is requested:
GenerateReport::dispatch($user->id);
A user clicks the button twice.
Now you have:
GenerateReport GenerateReport
Both jobs can run.
For expensive operations, that may be unnecessary.
Laravel provides a simple solution.
Make the Job Unique
Implement:
ShouldBeUnique
on your job:
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Contracts\Queue\ShouldBeUnique;
class GenerateReport implements ShouldQueue, ShouldBeUnique
{
public function __construct(public int $userId) {
}
public function handle(): void{
// Generate report...
}
}
Now Laravel prevents another copy of the same unique job from being dispatched while the existing unique job is still in the queue or processing.
Decide What Makes a Job Unique
By default, Laravel uses the job's class and serialized properties to determine uniqueness.
But you can explicitly define a unique ID:
public function uniqueId(): string
{
return (string) $this->userId;
}
Now:
GenerateReport::dispatch(10);
GenerateReport::dispatch(10);
share the same unique ID.
But:
GenerateReport::dispatch(10);
GenerateReport::dispatch(20);
are considered different jobs.