A job marked unique so it cannot be queued twice, and a worker killed mid-run leaving the lock held for its full duration.
final class RebuildSearchIndex implements ShouldQueue, ShouldBeUnique
{
public int $uniqueFor = 3600; // one hour
public int $timeout = 300; // five minutes
// uniqueFor must exceed the job's real duration and
// should not exceed it by much: a killed worker holds
// the lock for uniqueFor, not for timeout.
}
The hour was chosen when the job took forty minutes; it now takes four, and a worker killed during a deploy blocked the next run for fifty-six minutes of nothing. Setting uniqueFor to a little over the observed p99 and releasing the lock explicitly in a failed() handler covers both directions, and neither is the default.