New in Laravel 13.35. php artisan schedule:interrupt asks scheduled tasks to stop, before a deployment for example. But a command already running, especially in the background (runInBackground()), did not hear it: it went to the end, or got killed in the middle of a batch.
Since Laravel 13.35
The interruption is now timestamped, and Schedule::hasBeenInterruptedSince() tells whether it happened since a given moment. A long command checks it at a point where stopping breaks nothing:
use Illuminate\Console\Scheduling\Schedule; public function handle(Schedule $schedule) { $start = now(); foreach ($this->batches() as $batch) { if ($schedule->hasBeenInterruptedSince($start)) { return; } $this->process($batch); } }
Comparing with the start time, and not with "an interruption exists", matters: the signal of yesterday's deployment stays in the cache, and must not block the next runs.
Your task
The reminders:send command sends reminders for unpaid invoices every night, in batches of ten. A batch that has started must finish: stopped in the middle, it would remind some customers twice.
Make it stop between two batches when schedule:interrupt has been run since it started. The remaining invoices will go on the next run.