Laravel Queue and Jobs - How to re run failed job later on

Stefan Bogdanescu

Founder & Senior Architect · 2026-06-29

Laravel Company
# Laravel Queue and Jobs: How to Re-run Failed Jobs Later On Thank you for bringing up this very common and critical scenario in any application utilizing asynchronous processing. When dealing with background jobs, failures are inevitable—due to network issues, temporary database unavailability, or unexpected syntax errors during execution. The fact that these failed jobs are recorded in the `failed_jobs` table is Laravel’s built-in mechanism for ensuring no work is lost, but knowing how to recover them is the next crucial step. This post will walk you through exactly how to diagnose, manage, and most importantly, re-run those failed jobs so your tasks can be completed successfully. ## Understanding the Failure Mechanism When a queued job throws an unhandled exception, the queue worker marks that job as failed and persists the entire payload (the job class, the arguments, and the stack trace) into the `failed_jobs` database table. This is a safety net; it prevents the job from being lost indefinitely. However, this mechanism itself does not automatically re-run the job. You need an explicit action to trigger a retry. The key to recovery lies in understanding that the failure is stored as data, and you must interact with that data using Laravel’s Artisan commands or administrative tools. ## Methods for Re-running Failed Jobs There are several ways to approach re-running a failed job, depending on whether you want a quick manual retry or a more structured, automated recovery process. ### 1. Manual Re-queuing via Artisan The most direct way to address a single failed job is by using the `php artisan queue:retry` command or by manually managing the failed records. While Laravel doesn't offer a single "re-run this specific job" command, you can often leverage other commands in conjunction with your queue driver configuration. However, for truly complex scenarios, developers often rely on administrative tools. If you are using a package like **Laravel Horizon** (which provides excellent dashboard management for queue workers), Horizon offers built-in functionality to inspect failed jobs and retry them directly from the interface. This is often the easiest method for operational teams. ### 2. The Developer Approach: Fixing and Re-dispatching If you have fixed the underlying bug in your code—for instance, fixing a syntax error or addressing an external API failure—the best practice is not just to retry the old failed entry, but to re-dispatch the job from its source. If you are dealing with jobs that were dispatched via the standard `dispatch()` method, you simply need to execute the logic that *caused* the dispatch again. For instance, if a controller dispatches an email job: ```php // Before failure (Example) MailJob::dispatch($user->email)->onQueue('emails'); // After fixing the error and re-running the process: // Simply repeat the dispatch command once the code is fixed. MailJob::dispatch($user->email)->onQueue('emails'); ``` This ensures that the job enters the queue correctly, bypassing the stale failed record, provided your queue system is configured to handle redelivery gracefully. This aligns perfectly with the principles of robust architecture discussed in official Laravel documentation, emphasizing clean separation between application logic and background processing. ## Best Practices for Failure Management Relying solely on manual intervention is unsustainable for high-volume applications. Here are some essential best practices to prevent this situation from recurring: 1. **Robust Exception Handling:** Always wrap critical logic within `try...catch` blocks inside your Job classes. Catch specific exceptions, log the detailed error information, and re-throw a custom exception or handle the failure gracefully. This prevents raw PHP errors from being treated as fatal job failures. 2. **Logging is King:** Ensure that when an exception occurs, you log not just the stack trace to the `failed_jobs` table (which Laravel does), but also detailed context about *why* it failed. Use your chosen logging mechanism to record external context necessary for debugging later. 3. **Monitoring Tools:** Implement monitoring solutions (like Sentry or dedicated queue monitoring tools) that alert you immediately when a job enters the failed state. This allows for immediate attention, drastically reducing the time between failure and recovery. ## Conclusion Recovering failed jobs is less about finding a magic button and more about establishing a solid error-handling strategy. While Laravel provides the infrastructure to store these failures in the `failed_jobs` table, true recovery involves fixing the application logic, ensuring robust exception handling, and using appropriate administrative tools to re-dispatch valid work. By adopting these practices, you move from reactive debugging to proactive system management, building a more reliable and resilient application on Laravel.