Skip to main content

Was ist nebenläufige Verarbeitung?

Wenn Sie mehrere Anfragen an externe APIs oder Datenbank-Aggregationen, die nicht voneinander abhängen, nacheinander ausführen, entspricht die Gesamtdauer der Summe der einzelnen Laufzeiten. Führen Sie sie hingegen gleichzeitig aus, verkürzt sich die Gesamtdauer auf die Zeit der langsamsten Einzelverarbeitung. Die Facade Concurrency von Laravel realisiert eine solche nebenläufige Ausführung über eine einfache API.
Die Facade Concurrency wurde in Laravel 11 eingeführt und steht auch in Laravel 13 weiterhin zur Verfügung. Der Standardtreiber verwendet PHP-Kindprozesse und benötigt keine zusätzlichen Pakete.

Funktionsweise

Die Facade Concurrency serialisiert die übergebenen Closures, schickt sie an einen versteckten Artisan-Befehl und lässt sie jeweils in einem separaten PHP-Prozess ausführen. Nach Abschluss werden die Rückgabewerte serialisiert und an den Elternprozess zurückgereicht. Es stehen drei Treiber zur Verfügung:

Grundlegende Verwendung

Concurrency::run()

Übergeben Sie der Methode run() ein Array mit Closures, werden diese nebenläufig ausgeführt. Der Rückgabewert enthält die Ergebnisse der jeweiligen Closures als Array.
Sie können die Ergebnisse mit einem Array-Destructuring in einzelne Variablen aufteilen. Die Reihenfolge der Closures entspricht der Reihenfolge der Rückgabewerte.

Treiber angeben

Um einen bestimmten Treiber zu verwenden, nutzen Sie die Methode driver().
Um den Standardtreiber zu ändern, veröffentlichen Sie die Konfigurationsdatei und passen die Option default an.

Verwendung des fork-Treibers

Der fork-Treiber ist schneller als der process-Treiber, funktioniert aber ausschließlich in PHP-CLI-Umgebungen (z. B. in Artisan-Befehlen oder Queue-Workern). Innerhalb eines Web-Requests kann er nicht verwendet werden. Installieren Sie vor der Nutzung das Paket spatie/fork.
Der fork-Treiber funktioniert nicht während eines Web-Requests. Verwenden Sie ihn, wenn Sie nebenläufige Verarbeitung innerhalb eines Artisan-Befehls oder Queue-Workers wünschen.

Ohne Rückgabewerte: Concurrency::defer()

Interessieren Sie sich nicht für die Ergebnisse und möchten die Verarbeitung im Hintergrund nach dem Senden der HTTP-Antwort ausführen, verwenden Sie die Methode defer().
Beim Aufruf von defer() werden die Closures noch nicht ausgeführt. Sie laufen erst nebenläufig, nachdem die HTTP-Antwort an den Nutzer gesendet wurde.
defer() eignet sich hervorragend für Arbeiten, bei denen der Nutzer nicht warten muss – etwa das Aufzeichnen von Analytics oder das Vorwärmen von Caches.

Praxisbeispiel: mehrere externe APIs gleichzeitig aufrufen

Nehmen wir das Dashboard eines E-Commerce-Systems, das Daten aus drei APIs bezieht: Bestandsführung, Umsatzstatistik und Versandstatus.

Sequenzielle Ausführung (vor der Optimierung)

Nebenläufige Ausführung (nach der Optimierung)

Braucht jede API 1 Sekunde, ergibt sich sequenziell eine Gesamtlaufzeit von 3 Sekunden, nebenläufig hingegen nur etwa 1 Sekunde.

Mehrere Datenbank-Aggregationen gleichzeitig

Wenn Sie den process-Treiber für Datenbank-Aggregationen verwenden, öffnet jeder Kindprozess eine eigene Datenbankverbindung. Achten Sie bei hoher Parallelität auf die maximale Verbindungsanzahl Ihrer Datenbank.

Konfiguration für Tests

In Testumgebungen führt der sync-Treiber die Closures nacheinander aus. Es entfällt der Overhead durch das Starten von Prozessen, wodurch Tests schneller laufen.
Alternativ können Sie den Standardtreiber in .env.testing festlegen.

Hinweise

Closures werden serialisiert und an Kindprozesse übergeben. Objekte, die nicht serialisierbar sind (Datenbankverbindungen, Datei-Handles, Ressourcen usw.), können nicht von außerhalb der Closure eingefangen werden. Erstellen Sie die benötigten Objekte innerhalb der Closure neu.
Der process-Treiber ist mit dem Aufwand für das Starten eines Kindprozesses verbunden. Ist die Verarbeitung selbst sehr kurz (wenige Millisekunden), bringt die nebenläufige Ausführung möglicherweise keinen Vorteil. Ihre Stärke spielt sie bei Arbeiten von 100 ms und mehr aus – etwa HTTP-Anfragen oder Datenbank-Aggregationen.
Der fork-Treiber forkt einen PHP-Prozess und kann daher nicht innerhalb eines Web-Requests (FPM oder Apache) genutzt werden. Verwenden Sie ihn ausschließlich in Artisan-Befehlen oder Queue-Workern.
Tritt während der nebenläufigen Ausführung eine Ausnahme auf, wirft run() diese erneut. Wenn Sie möchten, dass andere Verarbeitungen weiterlaufen, obwohl eine Closure fehlschlägt, fangen Sie die Ausnahme innerhalb der Closure mit try/catch ab.

Nächste Schritte

Queues und Jobs

Erfahren Sie, wie Sie Arbeit asynchron im Hintergrund über Queues und Jobs verarbeiten.
Zuletzt geändert am 13. Juli 2026