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

  1. Implement the contract – add implements Interruptible to the job class definition.
  2. Check the flag inside the work loop – insert a check each iteration to see if the job should stop.
  3. 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 stopwaitsecs higher 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

  1. Dağıtım betiklerini --once bayrağı için tarayın ve kesilebilir işlerin kullanıldığı daemon modu ile değiştirin.
  2. En uzun süren işleri (on binlerce satıra dokunan veya birkaç dakika sürenler) belirleyin ve Interruptible kontratını ekleyin.
  3. Her döngü yinelemesinin içine bir bayrak kontrolü yerleştirin ve gerekli tüm sonlandırma kodlarını interrupted() metoduna taşıyın.
  4. Dağıtımların işlemeyi ne sıklıkta etkilediğine dair metrikler toplamak için WorkerInterrupted ve JobInterrupted olaylarına dinleyiciler bağlayın.
  5. Redis veya veritabanı kuyrukları için birikmiş işleri (backlog) izlemek üzere totalSize() kullanın; SQS için CloudWatch alarmlarını mevcut haliyle koruyun.

Dağıtım kaynaklı kapatmaları ani bir durdurma yerine koordine bir adım olarak ele alın. Laravel 13.31 verileri tutarlı tutar ve yarıda kalmış işlerin yarattığı operasyonel zorlukları hafifletir. Bunun karşılığında kod sorumluluğunda küçük bir artış yaşanır, ancak yoğun arka plan işlemeye dayanan ekipler daha güvenilir bir üretim ortamı kazanır.