Bei den meisten Deployments entsteht ein Zeitfenster, in dem der Code auf der Festplatte aktualisiert ist, die Worker aber noch die alte Version ausführen. Worker, die in diesem Fenster neue Jobs reservieren, deserialisieren Payloads aus dem alten Code und führen sie mit dem neuen Code aus – gelegentlich treten Ausfälle auf, wenn Job-Klassen umbenannt oder Konstruktor-Signaturen geändert werden.

Laravel 13.25 bietet einen globalen Pausierungsschalter, der alle Worker auf allen Verbindungen stoppt, neue Jobs zu reservieren, ohne den HTTP-Verkehr zu beeinflussen. Die bisherigen Workarounds – Wartungsmodus (stoppt mehr als nur Queues) und queue:restart (ein Wunsch, keine Garantie) – werden durch diese dedizierte Lösung ergänzt.

Die Befehlssyntax ist einfach: php artisan queue:pause --all und php artisan queue:resume --all. Das queue-Argument wird optional; ohne --all funktionieren Befehle wie zuvor mit einem connection:queue-Paar. Die gleiche Funktionalität steht über die Queue-Facade für PHP-basierte Deploy-Skripte oder Admin-Controller zur Verfügung mit Queue::pauseAll() und Queue::resumeAll().

Pausieren stoppt Worker daran, neue Jobs zu reservieren, hält Worker-Prozesse aber am Leben und in einer Schleife; sie schlafen nur, anstatt zu arbeiten. Jobs, die bereits verarbeitet werden, wenn die Pausierung aktiviert ist, laufen bis zum Ende. Erzeuger sind nicht betroffen: SomeJob::dispatch() schreibt weiterhin in Redis oder die Datenbank, und diese Jobs bleiben bis zur Wiederaufnahme in der Warteschlange.

Die Implementierung verwendet einen einzigen Cache-Schlüssel, illuminate:queues:paused, gesetzt mit forever(). Worker prüfen bereits bei jeder Schleife den Cache auf Restart- und per-Queue-Pausierungssignale; der globale Schlüssel wird im selben many()-Aufruf abgerufen und fügt keine zusätzlichen Round Trips hinzu. QueueManager::isPaused() und getPausedQueues() melden eine Warteschlange als pausiert, wenn entweder der globale Schlüssel oder der individuelle Schlüssel gesetzt ist.

Die globalen und individuellen Pausierungsmechanismen sind unabhängig. Wenn eine Warteschlange vor dem Deployment individuell pausiert wurde, lässt resumeAll() sie pausiert – eine bewusste Designentscheidung. Jemand könnte die Warteschlange absichtlich angehalten haben, um einen fehlerhaften Job zu untersuchen, und ein automatisiertes Deployment sollte manuelle Maßnahmen nicht stillschweigend rückgängig machen. Das Löschen einzelner Pausierungen erfordert weiterhin queue:resume connection:queue.

Zwei neue Events begleiten die existierenden pro-Queue-Events QueuePaused und QueueResumed: QueuesPaused und QueuesResumed werden bei globaler Pausierung oder Wiederaufnahme ausgelöst, sodass Anwendungen diese Deployment-Aktionen protokollieren oder überwachen können.

Das Feature wurde von Jack Bayliss in Pull Request #61126 beigetragen.