spatie/laravel-failed-job-monitor
Spatie's Laravel Failed Job Monitor sends notifications when a queued job fails. It uses Laravel's native notification system and can alert via mail or Slack, with configuration for enabled status, channels, email addresses, and Slack webhook URL.
Architecture fit
Illuminate\Queue\Events\JobFailed event and dispatches a Laravel notification. It introduces no new persistence, no new infrastructure, and no queue/driver coupling — it works with any Laravel queue backend (Redis, SQS, database, sync) and with Horizon.notification and notifiable are config-swappable classes, so we can route to PagerDuty/Opsgenie/Teams via a community or in-house notification channel without forking.Integration feasibility
composer require + vendor:publish + four env vars — an afternoon of work, not a project. PHP 8+ and Laravel 9–13 are supported by current 4.x releases; the enabled flag (4.5.0) makes it safe to ship the same config to every environment and disable locally/CI.guzzlehttp/guzzle, which is already a transitive dependency in nearly all Laravel apps; effectively a no-op.notificationFilter closures break php artisan config:cache (LogicException: Your configuration files are not serializable). Any production deployment that caches config must use a static callable class. This must be in the implementation checklist, not discovered in a deploy pipeline.FAILED_JOB_CHANNELS and FAILED_JOB_EMAILS are comma-split env strings — acceptable, but they mean alert routing lives in env vars, not in code review or a config management system. For anything on-call-critical this is a governance smell.Technical risk
Dependents: 0 in the supplied metadata is almost certainly an indexing artifact and should not be read as adoption risk.JobFailed listener that throws leaves you with a false sense of coverage and no signal that coverage is gone.ShouldQueue, a slow or hanging Slack/webhook call blocks the worker loop after every failure — exactly when the system is already unhealthy. Verify and, if needed, supply a queued custom notification.Key questions
notifiable/channel to reach PagerDuty/Opsgenie?Stack fit
Migration path
Compatibility
^4.x and validate against the app's Laravel/PHP matrix at install time; the package tracks new Laravel majors with some lag, so treat it as an item on every framework-upgrade checklist rather than an assumption.php artisan config:cache succeeds post-integration with the filter class (not closure) in place — make this an explicit acceptance criterion in the PR.Sequencing
FAILED_JOB_* envs to staging only.notificationFilter by job class/queue to suppress known-flaky, non-actionable failures; establish storm handling (see below).Maintenance
Support
Scaling
notifiable class (or per-service configs) — the default sends everything to one mailing list and one Slack webhook. That is workable for a single product team and becomes a bottleneck past roughly three owning teams.Failure modes
| Mode | Impact | Mitigation |
|---|---|---|
| Alert storm from systemic outage | Slack 429s, mail quota exhaustion, alert fatigue, missed real signals | notificationFilter by job/queue, digest channel for bulk queues, route critical only to paging |
| Monitor silently broken (bad webhook/SMTP) | False confidence, undetected coverage gap | Scheduled synthetic canary job in staging+prod; alert on canary absence |
| Inline notification blocks worker | Slower queue drain during incidents | Use a ShouldQueue custom notification; confirm before rollout |
Closure filter breaks config:cache |
Deploy pipeline failure | Enforce static callable class; gate in CI |
| Package lag on new Laravel major | Blocks framework upgrade | Track as an upgrade-checklist dependency; have a one-line removal fallback |
| No aggregation means the same failure notified N times | Noise, no signal on blast radius | Complement with Horizon/APM failure-rate dashboards |
Ramp-up
TPM verdict: High-ROI, low-complexity gap-closer for Laravel services that currently have no failed-job notification, and a reasonable consolidation target if the team is running two or three overlapping ad-hoc alerts. It should be shipped as a first-line, best-effort notification layer — never as the sole paging path — with storm filtering and a canary designed in from day one. The package is not the risk; the unmanaged alert volume and the untested delivery path are.
How can I help you explore Laravel packages today?