Laravel 13.31 adds interruptible jobs, letting queue workers catch the SIGTERM signal sent during deployments and shut down cleanly instead of aborting a task halfway through. Teams that run long jobs—processing tens of thousands of rows, sending bulk emails, or generating reports—benefit because data stays consistent when a new release rolls out.
Why deployments have been killing jobs
When a new version lands, process managers such as Supervisor, Docker, and Kubernetes tell existing workers to stop by sending SIGTERM, a polite request to terminate. Most workers wait for the current job to finish before exiting. The problem appears when the manager grants only a few seconds to comply. If a job needs minutes, the manager escalates to SIGKILL, killing the process instantly. The job never reaches a consistent state, leaving partially updated records, orphaned files, or duplicate work.
Laravel’s answer: cooperative interruption
Laravel 13.31 introduces a contract named Interruptible that a job class can implement to become aware of the termination request. When SIGTERM arrives, Laravel calls the job’s interrupted() method. The framework does not stop the job automatically; the job must check a flag that Laravel sets and exit on its own. This cooperative model lets developers finish the current loop iteration, roll back partial changes, or write a checkpoint before quitting.
How to make a job interruptible
- Implement the contract – add
implements Interruptibleto the job class definition. - Check the flag inside the work loop – insert a check each iteration to see if the job should stop.
- Perform cleanup – in
interrupted(), persist any state that will allow the job to resume later, or log the interruption for later analysis.
The biggest trap: don’t use --once
Running the queue worker with php artisan queue:work --once disables signal handling entirely. The worker processes a single job and exits, but it never registers the SIGTERM handler. Consequently, any interruptible job ignores the termination request and is killed mid-process. This pattern shows up in cron-driven containers and one-shot deployments. Fix it by running the daemon mode (php artisan queue:work) whenever you need interruptible jobs.
Watching for interruptions
Laravel fires two events you can hook into:
- WorkerInterrupted – emitted whenever any worker receives a SIGTERM. Logging this event gives a high-level view of how often deployments interrupt workers.
- JobInterrupted – emitted only if the current job implements the Interruptible contract. Use this event to trigger job-specific cleanup, such as deleting temporary files or updating a “last processed row” marker.
Listening to these events lets teams build dashboards that show deployment impact and spot jobs that frequently get cut short.
Queue size reporting gets a tweak
The release adds a totalSize() method to the queue manager, returning the total number of pending jobs across all queues. The value is reliable for database-backed and Redis drivers, which report actual counts. Drivers like SQS, Sync, and Beanstalkd still return zero because they don’t expose a count through Laravel’s API. Teams using SQS should keep relying on CloudWatch metrics for queue depth.
What this means for different setups
- Docker/Kubernetes – the graceful shutdown period can now be used effectively. Extend the termination grace period so jobs have a few seconds to notice the flag and exit cleanly.
- Supervisor – set
stopwaitsecshigher than the time you expect a job to finish after receiving the interrupt flag. - Legacy jobs – review any job that runs longer than the manager’s timeout and, where feasible, make it interruptible.
Counter-point: added complexity
The feature does not replace proper timeout configuration. If a job’s loop never checks the interruption flag, the manager will still send SIGKILL. Teams must audit long-running code paths and insert checks at logical breakpoints. Some developers may find the extra boilerplate—implementing a contract and adding flag checks—unappealing for short jobs that already finish within the shutdown window.
Action checklist
- Scansionare gli script di deployment alla ricerca del flag
--oncee sostituirlo con la modalità daemon laddove vengono utilizzati job interrompibili. - Identificare i job più lunghi (quelli che toccano decine di migliaia di righe o che girano per diversi minuti) e aggiungere il contract
Interruptible. - Inserire un controllo di un flag all'interno di ogni iterazione del ciclo e spostare qualsiasi codice di finalizzazione necessario nel metodo
interrupted(). - Collegare dei listener a
WorkerInterruptedeJobInterruptedper raccogliere metriche su quanto spesso i deployment influenzino l'elaborazione. - Per le code Redis o del database, utilizzare
totalSize()per monitorare il backlog; per SQS, mantenere attivi gli allarmi CloudWatch.
Tratta gli shutdown causati dai deployment come un passaggio coordinato piuttosto che come un'interruzione brusca. Laravel 13.31 mantiene la coerenza dei dati e riduce i mal di testa operativi legati ai job incompleti. Il compromesso è un modesto aumento della responsabilità del codice, ma i team che si affidano a un'intensa elaborazione in background ottengono un ambiente di produzione più affidabile.
