NewWe open-sourced 50+ Laravel packages
Custom AI apps, agents and automation — Roundly ConsultingRoundly
All packages
CommandDoes
notifications:sweep {--only=}Expire stale claims, release due mail (held, trailing, retries, held interop mail), start due digests, fire due reminders and escalations. --only=claims,deliveries,digests,reminders,escalations. Prints the SweepReport.
notifications:pruneForce-delete old rows in chunks: read and archived (or deleted) inbox items, terminal deliveries, finished digest runs with no live entry, terminal reminders with no pending or firing escalation (after the prune.* durations), and receipts after idempotency.ttl.
notifications:typesThe registry: key, category, channels, priority, flags, window, reminder rules.
notifications:doctorChecks the setup and exits non-zero on an error (see below).
notifications:installPublishes the config and the migrations (refuses when a configured table exists) and prints the schedule lines and trait snippets.
notifications:reminders:sync {type?}Backfill: schedules reminders for every subject of a type’s class — every type with reminder rules when omitted.
php artisan notifications:sweep
php artisan notifications:sweep --only=deliveries,digests
php artisan notifications:prune
php artisan notifications:types
php artisan notifications:doctor
php artisan notifications:install
php artisan notifications:reminders:sync contract.expiring

Scheduling

Nothing is auto-scheduled:

// routes/console.php
use Illuminate\Support\Facades\Schedule;

Schedule::command('notifications:sweep')->everyMinute()->withoutOverlapping(10)->onOneServer();
Schedule::command('notifications:prune')->daily();

From PHP

$report = Notifications::sweep();                   // SweepReport: deliveries, digests, reminders, escalations, expired
Notifications::sweep(['reminders', 'escalations']);
$pruned = Notifications::prune();                   // PruneReport: inboxItems, deliveries, digestRuns, reminders, receipts, total()

Notifications::deliveries()->dispatchDue();         // int
Notifications::digests()->sendDue();                // int
Notifications::reminders()->fireDue();              // FiredReminders: reminders, escalations

What the doctor checks

LevelFinding
errornotifications.key_type differs from options.key_type.
infoThe queue connection is sync: mail, digests and fan-out run inline. Also prints the schedule line.
warningThe preference lock store uses the array or file driver — not shared across servers.
errorA config value that does not read (e.g. invalid default quiet hours).
errorA type whose subject has no policy while the ability is not defined — the first send throws.
error / warningInterop: a map to an unknown type or a broken time-critical guard (errors); a digestible mapped type, a subject type without subjectFrom() (warnings).
error / warningThe user model cannot be mailed (error) or is not Authenticatable (warning).

Show your open-source love

This package is free and MIT-licensed. If it saves you time, a one-off donation or a Patreon membership keeps it maintained, tested and documented.

More ways to support, including crypto

By donating, you agree to our donation terms.

Want this built into your product?

We integrate our packages into custom Laravel and AI builds. Tell us what you're working on and we'll reply within 48 hours.