Skip to content
OpenCloseEsc
Tips
  • Laravel
  • queue
  • concurrency

Keep one copy of a job in the queue with ShouldBeUnique

A job that implements ShouldBeUnique is not dispatched again while an identical one is waiting or running, so a burst of events produces one run instead of fifty.

1 min read

Rebuilding a report after every change is wasteful when fifty changes arrive in a minute. Let the job itself refuse duplicates.

class RebuildReport implements ShouldQueue, ShouldBeUnique
{
    public int $uniqueFor = 300;
 
    public function __construct(public readonly int $accountId) {}
 
    public function uniqueId(): string
    {
        return (string) $this->accountId;
    }
 
    public function handle(): void { /* ... */ }
}

The lock is taken at dispatch and released when the job finishes, or after $uniqueFor seconds if it never does. uniqueId() scopes it, so one account's rebuild does not block another's. It needs a cache driver that supports locks (Redis, database, Memcached, DynamoDB).

To block only while the job is running, not while it waits, implement ShouldBeUniqueUntilProcessing instead.