Wanneer schaalt je Laravel-monoliet niet meer? Leer de signalen herkennen, gebruik een modular monolith als tussenstap en weet wanneer microservices écht de juiste keuze zijn.
Microservices met Laravel — wanneer monolith niet meer schaalt
80% van de Laravel-projecten heeft geen microservices nodig. Die 20% die het wel heeft, wacht vaak te lang. Het resultaat: een monoliet die op zijn tandvlees loopt, deployments die uren duren, en teams die elkaar constant blokkeren. Dit artikel gaat over het herkennen van dat omslagpunt — en wat je er daadwerkelijk aan doet.
Microservices met Laravel zijn geen silver bullet. Ze lossen echte problemen op, maar creëren ook nieuwe. Wij zien bij klanten dat de meeste problemen niet met een architectuurshift, maar met betere module-scheiding en duidelijkere servicelagen te fixen zijn.
Signalen dat je monoliet knelt
Een monoliet schaalt prima tot een bepaald punt. Dat punt verschilt per project. Maar er zijn concrete signalen die vertellen wanneer je de grens nadert.
Deployments blokkeren teams. Als een bugfix in de checkout wacht op een feature in de productcatalogus, verlies je tempo. Twee teams, één codebase, één deploymoment: dat is structureel probleem. Database wordt een knelpunt. Queries die tables locken, writes die reads vertragen — zodra je database de bottleneck is en indexoptimalisatie niet meer helpt, is schalen op de databaselaag noodzaak. Feature-teams bijten op elkaars PR's. Merge conflicts elke sprint, tests die falen door wijzigingen in een andere module, niemand weet meer wat wat breekt. In de praktijk zien we dit al bij teams van drie developers op een codebase van 100k+ regels. Specifieke onderdelen hebben andere schaalbehoeften. De feed-generator draait één keer per nacht en is CPU-intensief. De checkout verwerkt pieken van 10x normaal verkeer. Als je alles op dezelfde servers draait, betaal je altijd voor het piekgeval. Externe integraties blokkeren de kern. Een ERP-koppeling die soms 30 seconden wacht, een third-party API die down gaat en daarmee je gehele request-queue verstopt. Dat zijn integratiefouten, geen architectuurfouten — maar ze wijzen op grenzen die beter extern moeten liggen.Modular monolith: de verplichte tussenstap
Stap niet direct van een ongestructureerde monoliet naar microservices. Dat is technische schuld inruilen voor operationele chaos. De modular monolith is de slimste tussenstap.
Een modular monolith is één Laravel-applicatie, opgedeeld in duidelijk afgebakende modules met harde grenzen. Modules praten niet direct met elkaars modellen — alleen via expliciete interfaces of events. De database kan gedeeld blijven, de deployment ook.
// app/Modules/Catalog/CatalogServiceProvider.php
namespace App\Modules\Catalog;
use Illuminate\Support\ServiceProvider;
class CatalogServiceProvider extends ServiceProvider
{
public function register(): void
{
$this->app->bind(
\App\Modules\Catalog\Contracts\ProductRepositoryInterface::class,
\App\Modules\Catalog\Repositories\EloquentProductRepository::class,
);
}
public function boot(): void
{
$this->loadRoutesFrom(__DIR__ . '/routes.php');
$this->loadMigrationsFrom(__DIR__ . '/database/migrations');
}
}
Elke module heeft zijn eigen routes, migrations en repository-implementatie. De rest van de applicatie spreekt alleen de interface aan — nooit het Eloquent-model direct.
Dit levert drie dingen op: betere testbaarheid, minder merge-chaos, en een codebase die je later gemakkelijker kunt opsplitsen als dat moment echt komt.
Service-grenzen bepalen
Als je na de modular monolith stap besluit dat microservices nodig zijn, is de eerste vraag: waar trek je de grenzen?
Domain-driven design is hier het meest betrouwbare kompas. Grenzen volgen business-domeinen, niet technische lagen. Niet "frontend-service" en "backend-service", maar "catalog-service", "checkout-service" en "fulfillment-service".Stel je de volgende vragen per potentieel domein:
| Vraag | Goed teken voor split | Blijf bij monoliet |
|---|---|---|
| Aparte deployment nodig? | Ja, andere releasecadans | Nee, altijd samen |
| Andere schaalbehoeften? | Ja, piekverkeer verschilt | Nee, gelijkmatig |
| Apart team ownership? | Ja, autonoom team | Nee, iedereen werkt er aan |
| Andere databehoefte? | Ja, eigen database logisch | Nee, hoge datakoppeling |
| Reikt over bedrijfsgrenzen? | Ja, extern team of vendor | Nee, intern domein |
Hoge datakoppeling is de gevaarlijkste reden om niet te splitsen. Als service A en service B constant elkaars data nodig hebben, betaal je de prijs van microservices zonder de voordelen. Reken op honderden extra HTTP-calls per paginalading als je dit fout doet.
Async communicatie via queues en events
Microservices die synchroon met elkaar praten via HTTP zijn bijna net zo breekbaar als een monoliet — alleen moeilijker te debuggen. Async communicatie via queues en events is de juiste standaard.
Laravel biedt hiervoor uitstekende primitieven out-of-the-box.
// In de checkout-service: event dispatchen na afronden bestelling
use Illuminate\Support\Facades\Bus;
Bus::chain([
new ReserveInventory($order),
new ChargePayment($order),
new DispatchFulfillment($order),
])->dispatch();
// In de fulfillment-service: luisteren via een queue worker
// config/queue.php → Redis of SQS als broker
class OrderPlacedListener implements ShouldQueue
{
use InteractsWithQueue;
public function handle(OrderPlaced $event): void
{
FulfillmentOrder::createFromOrder($event->order);
}
}
Met Redis als queue-backend en Laravel Horizon als monitoring heb je doorgaans een setup die honderden jobs per seconde aankan zonder infrastructuuraanpassingen. Voor hogere throughput stap je over naar Amazon SQS of RabbitMQ.
Idempotentie is geen optie, het is vereiste. Een queue-job kan twee keer uitgevoerd worden. Je fulfillment-service mag niet twee keer dezelfde order aanmaken. Bouw dit in via unieke sleutels of database-constraints, niet via "het zal wel goed gaan".Wat je zeker niet moet doen
Eerlijkheid is hier op zijn plaats.
Splits niet voor de architectuur, splits voor een probleem. Als je monoliet prima werkt, is een microservices-migratie alleen maar kosten. Meer infrastructuur, meer netwerkcomplexiteit, moeilijkere distributed tracing, hogere operationele overhead. Reken op twee tot drie keer zoveel DevOps-tijd in de eerste zes maanden na een split. Distributed transactions zijn een nachtmerrie. Als checkout en inventory allebei hun eigen database hebben, is een gesynchroniseerde transactie over beide services bijzonder complex. Je hebt Saga-patterns, compensating transactions, of eventual consistency nodig. Elk van deze is correct te implementeren, maar geen van deze is simpel. Service discovery, secrets management, container orchestration. Een microservices-setup zonder Kubernetes of een vergelijkbaar platform schaal je handmatig. Dat is geen keuze die je wil maken boven de 10 services. Debugging wordt moeilijker. In een monoliet volg je een stacktrace. In microservices heb je distributed tracing nodig (Jaeger, Zipkin, of een betaalde oplossing). Zonder goede observability ben je blind.Wanneer blijf je bij de monoliet?
In de praktijk: bijna altijd. De meeste Laravel-projecten die wij bouwen voor e-commerce — van Magento-migraties tot maatwerk — draaien prima op een gestructureerde monoliet. Zelfs bij honderdduizenden orders per jaar.
Een monoliet die goed gemodulariseerd is, correcte database-indexen heeft en horizontaal schaalt via load balancing, haalt meer dan genoeg throughput voor de meeste shops. De complexiteit van microservices is alleen gerechtvaardigd als je concrete, meetbare problemen hebt die je met de monoliet architectuur niet kunt oplossen.
Shopify zelf draaide jarenlang op één grote Rails-monoliet voordat ze onderdelen begonnen te extraheren. Voor Shopify Plus-merchants geldt: de platformen waarop je bouwt, zijn al microservices. Je eigen integraties hoeven dat niet te zijn.
Stappenplan: van monoliet naar microservices
Als je besluit te gaan, doe het stap voor stap.
Stap 1: Modulariseer eerst. Breng orde in de monoliet voordat je iets extraheert. Zes maanden strakke module-grenzen geven je inzicht in wat werkelijk ontkoppeld is. Stap 2: Extraheer één service. Kies het minst-gecoupled domein. Vaak is dat iets als notificaties, rapport-generatie of een externe feed. Niet de checkout. Nooit de checkout als eerste. Stap 3: Zet async communicatie op. Redis queue, Horizon, een event-bus. Laat de eerste service volledig async werken voordat je een tweede extraheert. Stap 4: Bouw observability in. Logging, metrics, distributed tracing — voordat je de tweede service extraheert, niet erna. Stap 5: Herhaal langzaam. Elke service-extractie kost twee tot vier weken ontwikkel- en stabiliteitstijd. Plan dat in.Kosten en afwegingen op een rij
| Aspect | Monoliet | Modular monolith | Microservices |
|---|---|---|---|
| Deployment complexity | Laag | Laag | Hoog |
| Ontwikkelsnelheid (early) | Hoog | Hoog | Laag |
| Schaalbaarheid per domein | Beperkt | Beperkt | Hoog |
| Debugging | Eenvoudig | Eenvoudig | Complex |
| Infrastructuurkosten | Laag | Laag | Hoog (+40-80%) |
| Team-autonomie | Laag | Gemiddeld | Hoog |
| Datakoppeling risico | Laag | Laag | Hoog |
Reken bij microservices op 40 tot 80% hogere infrastructuurkosten ten opzichte van een vergelijkbare monoliet-setup. Container orchestration, service meshes, API gateways, extra monitoring — dat telt op.
Conclusie
Microservices met Laravel lossen echte problemen op voor teams die tegen concrete schaallimieten aanlopen. Maar die grens bereiken de meeste e-commerce projecten pas bij honderden developers of miljoenen dagelijkse transacties. Daarvoor niet.
Ga eerst voor een modular monolith. Stel harde module-grenzen in. Implementeer async via queues. Meet waar de bottlenecks zitten. Dan pas beslis je op basis van data of een service-extractie zinvol is.
Wil je sparren over de architectuur van jouw Laravel-platform? Neem contact op — geen sales, geen praatjes, gewoon een technisch gesprek.
Veelgestelde vragen
Wanneer is een Laravel-monoliet te groot voor verdere schaling?Er is geen harde grens in regels code of gebruikers. De echte signalen zijn: deployments die teams blokkeren, een database die consistent de bottleneck is ondanks optimalisaties, en feature-teams die constant op elkaars werk wachten. Pas dan heeft een architectuurshift business-waarde.
Wat is het verschil tussen een modular monolith en microservices?Een modular monolith is één applicatie met duidelijke interne grenzen tussen domeinen. Alles draait in hetzelfde proces en dezelfde deployment. Microservices zijn aparte processen met eigen databases en netwerkcommunicatie ertussen. De modular monolith geeft je 70% van de voordelen van microservices voor 20% van de operationele kosten.
Welke queue-broker past het beste bij Laravel microservices?Voor de meeste projecten is Redis met Laravel Horizon de pragmatische keuze: eenvoudig op te zetten, goede monitoring, en voldoende throughput tot meerdere honderden jobs per seconde. Bij hogere volumes of cross-service communicatie met garanties kijk je naar Amazon SQS of RabbitMQ.
Moet ik bij microservices aparte databases per service gebruiken?In theorie ja — dat is het principe van database-per-service. In de praktijk beginnen de meeste teams met een gedeelde database met schema-scheiding per domein. Dat is een pragmatische tussenstap. Volledig gescheiden databases per service vereisen distributed transaction management, wat aanzienlijk complexer is.

Geschreven door Ruthger Idema
15+ jaar ervaring in e-commerce development. Gespecialiseerd in Magento, Shopify en Laravel maatwerk.
Meer over ons team →