Skip to main content

Wat is concurrency?

Wanneer je meerdere taken die niet van elkaar afhankelijk zijn — zoals requests naar meerdere externe API’s of database-aggregaties — na elkaar uitvoert, is de totale tijd de som van alle afzonderlijke verwerkingstijden. Voer je ze tegelijk uit, dan wordt de totale tijd teruggebracht tot die van de langzaamste taak. Laravels Concurrency-facade maakt zulke parallelle uitvoering mogelijk met een eenvoudige API.
De Concurrency-facade is geïntroduceerd in Laravel 11 en is ook in Laravel 13 nog beschikbaar. De standaarddriver gebruikt PHP-childprocessen en werkt dus zonder extra packages.

Hoe het werkt

De Concurrency-facade serialiseert de doorgegeven closures, stuurt ze naar een verborgen Artisan-commando en voert ze elk uit in een apart PHP-proces. Zodra de verwerking klaar is, wordt de returnwaarde geserialiseerd en teruggestuurd naar het parent-proces. Er zijn drie drivers beschikbaar.

Basisgebruik

Concurrency::run()

Als je een array van closures aan de run()-methode doorgeeft, worden deze parallel uitgevoerd. Als resultaat ontvang je een array met de returnwaarden van elke closure.
Met array-destructuring kun je elk resultaat in een variabele opvangen. De volgorde van de closures en de volgorde van de returnwaarden komen overeen.

Een driver kiezen

Wil je een specifieke driver gebruiken, dan geef je die op met de driver()-methode.
Om de standaarddriver te wijzigen, publiceer je het configuratiebestand en pas je de default-optie aan.

De fork-driver gebruiken

De fork-driver is sneller dan de process-driver, maar kan alleen worden gebruikt in de PHP CLI-omgeving (Artisan-commando’s en queue workers). Binnen webrequests kun je hem niet gebruiken. Installeer vóór gebruik het spatie/fork-package.
De fork-driver werkt niet tijdens webrequests. Gebruik hem als je parallelle verwerking wilt uitvoeren binnen Artisan-commando’s of queue workers.

Geen resultaat nodig: Concurrency::defer()

Als je niet geïnteresseerd bent in het resultaat en de taken op de achtergrond wilt uitvoeren nadat de HTTP-response is verstuurd, gebruik je de defer()-methode.
Op het moment dat je defer() aanroept, worden de closures nog niet uitgevoerd. Ze worden parallel uitgevoerd nadat de HTTP-response naar de gebruiker is verzonden.
defer() is ideaal voor taken waarop de gebruiker niet hoeft te wachten, zoals het vastleggen van analytics-data of het opwarmen van de cache.

Praktijkvoorbeeld: meerdere externe API’s tegelijk aanroepen

Neem als voorbeeld een dashboard van een webshop dat informatie ophaalt uit drie API’s: voorraadbeheer, verkoopcijfers en verzendstatus.

Sequentiële uitvoering (vóór verbetering)

Parallelle uitvoering (na verbetering)

Als elke API 1 seconde nodig heeft, duurt sequentiële uitvoering in totaal 3 seconden, terwijl parallelle uitvoering in ongeveer 1 seconde klaar is.

Meerdere database-aggregaties tegelijk uitvoeren

Als je de process-driver gebruikt voor database-aggregaties, wordt er per childproces een nieuwe databaseverbinding opgezet. Let bij veel gelijktijdige uitvoeringen op het maximale aantal databaseverbindingen.

Configuratie voor tests

In de testomgeving voert de sync-driver de closures sequentieel uit. Er zijn geen opstartkosten voor processen, waardoor je tests sneller worden.
Je kunt de standaarddriver ook wijzigen in .env.testing.

Aandachtspunten

Closures worden geserialiseerd en doorgegeven aan het childproces. Objecten die niet geserialiseerd kunnen worden (databaseverbindingen, file handles, resources enzovoort) kun je niet van buiten de closure capturen. Maak benodigde objecten binnen de closure opnieuw aan.
De process-driver heeft opstartkosten voor childprocessen. Als de taak zelf heel kort is (enkele milliseconden of minder), levert parallelle uitvoering mogelijk geen snelheidswinst op. Parallellisatie loont vooral bij taken die 100 ms of langer duren, zoals HTTP-requests of database-aggregaties.
De fork-driver forkt PHP-processen en kan daarom niet worden gebruikt tijdens webrequests (FPM of Apache). Gebruik hem alleen binnen Artisan-commando’s of queue workers.
Als er tijdens de parallelle uitvoering een exception optreedt, gooit run() die exception opnieuw. Wil je dat de andere taken doorgaan als één taak een exception veroorzaakt, gebruik dan try/catch binnen de closure.

Volgende stap

Queues en jobs

Leer hoe je met queues en jobs taken asynchroon op de achtergrond uitvoert
Laatst gewijzigd op 6 september 2026