Updated June 2026. Tested on Laravel 13 and PHP 8.4. Part of the Techalyst queue series.
Here is a real incident. A pull request was merged by mistake and pushed one particular job to the queue more than a hundred thousand times. The PR was reverted, so the job class no longer exists, and now your workers keep picking up those jobs and erroring because they cannot resolve a class that is gone. You want to delete just those jobs, not purge the whole queue, which still holds plenty of legitimate work. There is a clever, simple fix.
The trap with the obvious options
Your first instinct might be queue:clear, but that wipes an entire queue, every job on it, good and bad alike. If the bad jobs are mixed in with real work, that is too blunt. And there is no built in "delete only jobs of class X" command, because the queue store does not index jobs by class for you to filter on.
# Nuclear option: deletes EVERY job on the connection/queue, not just the bad ones
php artisan queue:clear redis --queue=default
So if you cannot afford to lose the good jobs, you need another way.
The fix: a no-op job with the same name
The trick is to let the workers process the bad jobs successfully instead of erroring. When a worker pulls a job, it resolves the class named in the payload. The jobs are failing only because that class no longer exists. So bring the class back, but empty.
Recreate the job class with the exact same name and namespace as the removed one, and make its handle (or __invoke) method return immediately, doing nothing.
namespace App\Jobs;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Queue\Queueable;
class TheRemovedJob implements ShouldQueue
{
use Queueable;
public function handle(): void
{
return; // do nothing, just let it complete
}
}
Deploy that, and the workers start resolving these jobs again. Each one runs, does nothing, succeeds, and is removed from the queue. After a while the hundred thousand bad jobs drain away cleanly, while every legitimate job on the queue was processed normally the whole time.
Clean up afterwards
Once the bad jobs have drained (watch the queue size with Queue::size() until it settles), you can delete the temporary no-op class in a follow up deploy. It only needed to exist long enough for the workers to chew through the backlog.
Queue::connection('redis')->size('default'); // watch it fall
Wrapping up
To remove jobs of one specific type without nuking the whole queue, do not reach for queue:clear. Instead, recreate the offending job class with the same name and namespace and an empty handle() that returns immediately. The workers process those jobs successfully and they drop off the queue, leaving your legitimate jobs untouched. Remove the throwaway class once the queue size settles.
That wraps up the Techalyst queue series. Start at Laravel Queue Workers: How They Work for the foundations. Questions welcome below.
All comments ()
No comments yet
Be the first to leave a comment on this post.