laravel-failed-job-monitor: a notification when a queued job dies
Get notified when a queued job fails
At a glance
- What is it?
- spatie's laravel-failed-job-monitor sends a mail or a Slack message when a queued Laravel job fails, and it does it through Laravel's own notification system rather than by adding a transport of its own. The interesting part of the configuration is a filter that cannot be a closure, because Laravel's config cache cannot serialise one.
- Who is it for?
- laravel-failed-job-monitor fits a Laravel team that has never noticed a failed job because nobody was watching the failed_jobs table, and that wants a two line composer install and a Slack ping rather than a monitoring product. It does not fit a team that needs to know which job failed and why, because the package notifies rather than aggregates or groups, and it does not fit a team that has already built alerting on top of Laravel's queue events.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 2 days ago.
- What is it written in?
- Mainly PHP, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on November 7, 2026, and from our analysis. They are not legal advice.
Star history
- spatie/laravel-failed-job-monitor1,055 ★ · -1
| Repository | 2026-10-21 | 2026-11-07 |
|---|---|---|
| spatie/laravel-failed-job-monitor | 1.1k | 1.1k |
-1 Stars in the last 17 days, measured from the daily GitHub snapshot. Compare with other projects
Editorial analysis
What it does, and how little of it there is
This package sends notifications if a queued job fails. Out of the box it can send a notification via mail and/or Slack, and it leverages Laravel's native notification system.
That last clause is the design decision that makes the package worth its size. There is no webhook dispatcher of its own, no retry logic, no dashboard and no storage of history. The package plugs into the notification system that Laravel already has, which means the mail and Slack channels are the ones you already configured for the rest of your application, and if you later add another Laravel channel the failure notification goes there too.
What the package actually adds is the part that Laravel does not give you. Laravel records a failed job in the failed_jobs table, and someone has to notice. Most teams find out by looking, which is to say they find out from a customer. A monitor that turns the failure into a message is a small piece of code with an outsized effect on how quickly you find out.
The scope is narrow by design, and the README states it plainly: if you configured the package correctly, you are done, and you will receive a notification when a queued job fails. There is no configuration screen, no dashboard and no report.
The package is MIT licensed, the primary language is PHP, and the releases are on the 4.x line with 4.5.0 published on 2026-04-28, after 4.4.0 in March 2026 and 4.3.6 in February 2026.
Installation is two composer commands and a published config
The install is short, and there is one version note that will save a headache.
composer require spatie/laravel-failed-job-monitorFor Laravel versions 5.8 and 6.x, use v3.x of this package. The service provider will automatically be registered, so there is nothing to add to a providers array.
If you intend to use Slack notifications you should also install the Guzzle client.
composer require guzzlehttp/guzzleThen you must publish the config file, because the defaults are placeholders.
php artisan vendor:publish --tag=failed-job-monitor-configThe published file is where the notifiable is configured, and the defaults read from your environment file.
# Spatie Laravel-failed-job-monitor
FAILED_JOB_MONITOR_ENABLED=true
FAILED_JOB_CHANNELS=mail,slack
[email protected]
FAILED_JOB_SLACK_WEBHOOK_URL=The four variables are the whole configuration surface, and the channels variable is a comma separated list, so the same environment file can send to mail, to Slack, to both, or to neither once you disable it.
Two extension points, and the one that will bite you
The config file exposes two classes, and both are replaceable.
The notification class is the default notification, and it has support for mail and Slack. If you want a different one, you point the notification key at your own class. The notifiable class is the thing the notification is sent to, and the default notifiable uses the channels, mail and slack keys from the config to decide how the notification must be sent. That one is replaceable in the same way.
The third key is the filter. By default notifications are sent for all failures, and you can pass a callable to filter out certain notifications. The callable receives the notification, and if it returns false the notification is not sent.
Here is the trap, and the README handles it well. The closure form works only as long as Laravel does not support closure serialisation, so you get this error when you run php artisan config:cache.
LogicException : Your configuration files are not serializable.The recommended fix is to put the callable in a separate class and reference it as a callable pair, so the config stays serialisable.
class FailedJobNotification
{
public static function notificationFilter(Notification $notification): bool
{
return true;
}
}And then in the config file.
'notificationFilter' => [App\Notifications\FailedJobNotification::class, 'notificationFilter'],That is a small thing, but it is the kind of detail that only shows up on a deploy that caches configuration, which is to say in production.
Mail and Slack are channels, not the design
The channel configuration is short, and reading it tells you what the package is and is not.
'channels' => explode(',', env('FAILED_JOB_CHANNELS', 'mail,slack')),
'mail' => [
'to' => explode(',', env('FAILED_JOB_EMAILS', '[email protected]')),
],
'slack' => [
'webhook_url' => env('FAILED_JOB_SLACK_WEBHOOK_URL'),
],The channels list is a plain comma separated string, and the mail recipients are a comma separated string too, so a team can be addressed with one notification or several. The Slack side takes a single incoming webhook URL rather than a bot token and a channel, which is the simpler of the two approaches and the one most teams already have.
Two things are notably absent. There is no per-job filtering by queue or by exception type out of the box, which is what the notificationFilter is for, and there is no aggregation, so a deploy that breaks fifty jobs produces fifty notifications unless you write that logic into the filter yourself. That is a reasonable place to put the logic, since the filter receives the notification, but it means the noisy case is a problem you solve rather than a problem the package solves.
Turning the monitor off is one environment variable, FAILED_JOB_MONITOR_ENABLED=false, and the README suggests it for local development, where a queue that fails in a test run would otherwise page somebody.
A small package, a well known publisher, and a test command
The repository is small in the way a well scoped package is small. There is src/ for the code, config/ for the published configuration, tests/ for the test suite, composer.json, phpunit.xml.dist, a .php_cs.dist.php for the style rules, a .phpunit.result.cache, and a CHANGELOG.md and LICENSE.md.
The style configuration is the older PHP CS Fixer dot file, which is a small signal of the project's age, and the package still uses the artisan style commands. Testing is a composer script.
composer testThe publisher is Spatie, and the support section is the familiar pattern: a link to their open source packages, a request for a postcard with a public postcard wall, and a note that they invest resources in the packages. The credits name Freek Van der Herten, who wrote the original article this package came from, and there is a specific thank you to Egor Talantsev for his help creating v2 of the package.
The security route is email rather than the issue tracker, at [email protected], and the contributing guide is the shared one across their repositories.
The last push to the repository was on 2026-06-02, and the most recent release, 4.5.0, is from 2026-04-28, so the package is in a steady state rather than a neglected one. Nothing in the architecture is dated, because the architecture is Laravel's.
Editorial conclusion
laravel-failed-job-monitor fits a Laravel team that has never noticed a failed job because nobody was watching the failed_jobs table, and that wants a two line composer install and a Slack ping rather than a monitoring product. It does not fit a team that needs to know which job failed and why, because the package notifies rather than aggregates or groups, and it does not fit a team that has already built alerting on top of Laravel's queue events. Verify three things before you install it: that your Laravel version is one the 4.x line supports, since the README redirects 5.8 and 6.x to the v3 line, that you will publish the config file rather than relying on the defaults, because the Slack webhook and the recipient addresses all come from it, and that you set the filter as a class and not a closure, because a closure in the config breaks php artisan config:cache with a serialisation error.
Frequently asked questions
What does the laravel-failed-job-monitor package do?
It sends notifications if a queued job fails, out of the box via mail and/or Slack, and it leverages Laravel's native notification system rather than shipping its own transport. Once configured, you receive a notification when a queued job fails.
How do I install it and configure the channels?
Run composer require spatie/laravel-failed-job-monitor, add guzzlehttp/guzzle if you want Slack, and publish the config with php artisan vendor:publish --tag=failed-job-monitor-config. The channels come from FAILED_JOB_CHANNELS as a comma separated list, with FAILED_JOB_EMAILS for the recipients and FAILED_JOB_SLACK_WEBHOOK_URL for Slack.
Why does my notification filter break php artisan config:cache?
A closure in the config file cannot be serialised, so Laravel throws a LogicException saying your configuration files are not serializable. Put the callable in a separate class as a static method and reference it as an array of the class name and the method name in the notificationFilter key.
Can I send the failure notification somewhere other than mail or Slack?
Yes, by replacing the classes in the config. The notification key can point at your own notification class, and the notifiable key at your own notifiable class, and because the package uses Laravel's native notification system, any Laravel channel you already support can be used.
Which Laravel versions does the current release support?
The README notes that for Laravel versions 5.8 and 6.x you should use v3.x of this package, and the current line is 4.x, with 4.5.0 published on 2026-04-28. The service provider registers automatically, so only the config file needs publishing.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/spatie-laravel-failed-job-monitor)Star history chart for your README
[](https://hysenlabs.com/projects/spatie-laravel-failed-job-monitor)Was this useful?