Je WordPress-site groeit, het verkeer neemt toe en je merkt dat één server het niet meer trekt. De TTFB loopt op bij piekverkeer, de CPU piekt en je vraagt je af: hoe draai je WordPress op schaal met een multi-server setup? Het antwoord is minder ingewikkeld dan je denkt - maar het vereist wel een fundamenteel andere aanpak dan de klassieke single-server installatie.
In eerdere artikelen behandelden we hoe je performance bottlenecks herkent en meet en hoe je met technieken als full page caching en Redis object caching het maximale uit één server haalt. Maar er komt een punt waarop optimaliseren niet meer genoeg is. Dan is het tijd om horizontaal te schalen.
Verticaal vs. horizontaal schalen
Voordat je servers gaat toevoegen, is het goed om het verschil te begrijpen.
Verticaal schalen betekent je huidige server krachtiger maken: meer CPU-cores, meer RAM, snellere SSD's. Dit is de makkelijkste stap en vaak de eerste die je zet. Maar er zit een plafond aan - je kunt een server niet oneindig opschalen, en je hebt nog steeds een single point of failure.
Horizontaal schalen betekent meerdere servers inzetten die samen het werk doen. Een load balancer verdeelt het verkeer over twee of meer webservers, een aparte databaseserver handelt de queries af en gedeelde opslag zorgt dat uploads overal beschikbaar zijn.
Het voordeel van horizontaal schalen gaat verder dan alleen capaciteit. Je krijgt ook redundantie: als één webserver uitvalt, vangt de andere het verkeer op. Voor bedrijfskritische sites is dat een doorslaggevend argument.
De basisarchitectuur van een multi-server setup
Een typische multi-server WordPress architectuur bestaat uit deze lagen:
1. Load balancer
De load balancer is het eerste contactpunt voor bezoekers. Deze ontvangt alle inkomende verzoeken en verdeelt ze over je webservers. Populaire opties zijn NGINX als reverse proxy, HAProxy of een managed load balancer van je cloudprovider (zoals AWS ALB of DigitalOcean Load Balancer).
De load balancer bepaalt met een algoritme welke server het verzoek krijgt. De meest gebruikte methoden:
- Round robin - verzoeken worden om de beurt naar elke server gestuurd
- Least connections - de server met de minste actieve verbindingen krijgt het volgende verzoek
- IP hash - verzoeken van hetzelfde IP-adres gaan steeds naar dezelfde server (handig voor sessies, maar niet ideaal)
2. Webservers (applicatielaag)
Elke webserver draait een identieke WordPress-installatie met NGINX of Apache, PHP-FPM en dezelfde codebase. Het is cruciaal dat alle servers exact dezelfde plugins, thema's en configuratie hebben. Afwijkingen leiden tot onvoorspelbaar gedrag.
3. Databaseserver
In een multi-server setup draai je MySQL of MariaDB op een aparte server. Alle webservers verbinden met dezelfde database. Dit voorkomt dat PHP en MySQL op dezelfde machine om resources concurreren. In ons artikel over database optimalisatie behandelden we al hoe je MySQL optimaliseert - die kennis wordt hier extra waardevol.
4. Gedeelde opslag
Uploads, media en andere door gebruikers gegenereerde bestanden moeten op alle webservers beschikbaar zijn. Hier zijn meerdere oplossingen voor, die we verderop bespreken.
5. Redis-server
Een centrale Redis-server voor object caching is bij een multi-server setup niet optioneel maar essentieel. Alle webservers delen dezelfde cache, wat voorkomt dat elke server zijn eigen cache moet opbouwen.
Gedeelde uploads en bestanden
Dit is een van de eerste uitdagingen waar je tegenaan loopt. Als een gebruiker een afbeelding uploadt naar webserver A, is die niet automatisch beschikbaar op webserver B. Er zijn drie gangbare oplossingen:
NFS (Network File System)
Een NFS-share is een gedeeld bestandssysteem dat je op alle webservers mount. De wp-content/uploads-map wijst dan naar dezelfde fysieke locatie. Dit is eenvoudig op te zetten en werkt transparant voor WordPress.
Nadeel: NFS voegt netwerklatentie toe aan elke bestandsoperatie. Bij veel afbeeldingen op een pagina kan dat merkbaar worden. Bovendien is de NFS-server zelf een single point of failure tenzij je die ook redundant maakt.
Object storage (S3-compatibel)
Een modernere aanpak is het gebruik van object storage zoals Amazon S3, DigitalOcean Spaces of MinIO. Met een plugin als WP Offload Media worden uploads automatisch naar de bucket gestuurd en via een CDN uitgeleverd.
Voordeel: vrijwel onbeperkt schaalbaar, geen single point of failure en je combineert het direct met een CDN. Dit is de aanpak die de meeste grootschalige WordPress-sites gebruiken.
GlusterFS of Ceph
Voor wie volledige controle wil, zijn gedistribueerde bestandssystemen als GlusterFS of Ceph een optie. Ze repliceren bestanden automatisch over meerdere nodes. De configuratie is complexer, maar je bent niet afhankelijk van een externe dienst.
Sessies en gebruikerslogins delen
Standaard slaat PHP sessiedata op in het lokale bestandssysteem. In een multi-server setup betekent dit dat een gebruiker die inlogt op webserver A, bij het volgende verzoek op webserver B ineens uitgelogd kan zijn.
Er zijn twee oplossingen:
Sticky sessions
De load balancer stuurt verzoeken van dezelfde gebruiker steeds naar dezelfde server (meestal op basis van een cookie). Dit is de simpelste oplossing, maar ondermijnt het voordeel van load balancing - als de "sticky" server uitvalt, verliest de gebruiker zijn sessie alsnog.
Gedeelde sessie-opslag
De betere oplossing is sessies centraal opslaan. Redis is hier ideaal voor. Door PHP te configureren met session.save_handler = redis en session.save_path naar je Redis-server te laten wijzen, worden sessies automatisch gedeeld over alle webservers.
WordPress zelf slaat de meeste authenticatiedata in cookies (met tokens die tegen de database worden gevalideerd), waardoor het sessieprobleem minder groot is dan bij veel andere PHP-applicaties. Maar voor plugins die wél PHP-sessies gebruiken, is gedeelde sessie-opslag noodzakelijk.
Deployments en code-synchronisatie
Alle webservers moeten identieke code draaien. Handmatig bestanden kopiëren is foutgevoelig en niet schaalbaar. Er zijn betere manieren:
Git-based deployments
De meest betrouwbare aanpak is een deployment-pipeline die vanuit een Git-repository naar alle servers deployt. Tools als Deployer (een PHP-based deployment tool), Ansible of zelfs een eenvoudig CI/CD-script kunnen dit automatiseren. Bij elke push naar de production-branch wordt de code op alle servers tegelijk bijgewerkt.
Gedeeld bestandssysteem voor code
Je kunt de volledige WordPress-installatie op een NFS-share plaatsen, zodat alle servers letterlijk dezelfde bestanden lezen. Dit is eenvoudig maar heeft dezelfde nadelen als NFS voor uploads: latentie en een single point of failure. Voor code is de impact groter dan voor uploads, omdat PHP bij elk request tientallen bestanden moet lezen.
Container-based (Docker/Kubernetes)
Bij een container-gebaseerde aanpak bouw je een Docker-image met je volledige WordPress-installatie. Elke webserver draait een identieke container. Updates betekenen een nieuw image bouwen en uitrollen. Dit is de meest robuuste aanpak, maar ook de meest complexe om op te zetten.
Caching in een multi-server omgeving
Caching werkt anders wanneer je meerdere servers hebt. In ons artikel over full page caching bespraken we NGINX FastCGI Cache als snelste optie. In een multi-server setup heeft elke webserver zijn eigen lokale pagina-cache. Dat is prima - het betekent wel dat na een content-update de cache op alle servers geleegd moet worden.
Cache invalidatie
Dit is waar het complex wordt. Wanneer je een bericht publiceert of een pagina bijwerkt, moet de cache op alle webservers geleegd worden. Oplossingen:
- Purge via API - een deployment-hook of plugin stuurt een purge-verzoek naar elke webserver
- Redis-based cache tags - gebruik Redis om bij te houden welke pagina's gecacht zijn en stuur invalidatie centraal aan
- Korte cache-TTL - stel een lage time-to-live in (bijvoorbeeld 5 minuten), zodat verouderde content nooit lang blijft staan
Object cache
Zoals eerder genoemd is een gedeelde Redis-instantie essentieel. Zonder centrale object cache bouwt elke server zijn eigen cache op, wat leidt tot onnodig geheugenverbruik en inconsistente data. De autoloaded options die we eerder bespraken worden via Redis maar één keer opgehaald en vervolgens door alle servers hergebruikt.
De database schalen
De database is vaak de bottleneck in een multi-server setup. Alle webservers schrijven naar en lezen van dezelfde MySQL-server. Er zijn strategieen om dit te verhelpen:
Read replicas
Bij een primary-replica setup schrijft WordPress naar de primary database, terwijl leesquery's naar een of meer replica's gaan. De plugin HyperDB (oorspronkelijk ontwikkeld door Automattic) maakt dit mogelijk door WordPress-queries automatisch te routeren.
Dit is bijzonder effectief omdat WordPress overwegend leest - denk aan het laden van posts, opties en metadata. Schrijfoperaties (comments, post-updates) zijn relatief zeldzaam.
Query-optimalisatie
Naarmate je schaalt, worden inefficiente queries steeds pijnlijker. Wat op één server nauwelijks opvalt, kan bij honderd gelijktijdige verbindingen de database op zijn knieen brengen. De tips uit ons artikel over WP_Query onder de motorkap worden dan cruciaal.
Monitoring en health checks
In een multi-server setup is monitoring geen luxe maar noodzaak. Je load balancer moet weten of een webserver gezond is. Stel health checks in die regelmatig een URL op elke server opvragen - als een server niet reageert, wordt deze automatisch uit de pool gehaald.
Daarnaast wil je centraal loggen. Tools als Grafana met Prometheus of een ELK-stack (Elasticsearch, Logstash, Kibana) geven je inzicht in het gedrag van alle servers tegelijk. Zonder centraal overzicht is troubleshooting in een gedistribueerde omgeving een nachtmerrie.
Zoals beschreven in ons artikel over wat er tijdens een WordPress request gebeurt, doorloopt elk verzoek meerdere stappen. In een multi-server setup wil je per stap kunnen meten waar de tijd in gaat zitten - op welke server, voor welk verzoek.
Wanneer is een multi-server setup overkill?
Niet elke WordPress-site heeft meerdere servers nodig. Voordat je deze complexiteit toevoegt, controleer eerst of je het maximale uit je huidige setup haalt:
- Is full page caching correct geconfigureerd?
- Draai je Redis object caching?
- Zijn je autoloaded options opgeschoond?
- Is je database geoptimaliseerd?
- Gebruik je een CDN voor statische bestanden?
Een goed geoptimaliseerde single-server kan duizenden gelijktijdige bezoekers aan. Pas wanneer je dat plafond bereikt - of wanneer uptime-eisen dicteren dat je geen single point of failure kunt hebben - is horizontaal schalen de logische volgende stap.
Praktisch stappenplan
Wil je starten met een multi-server setup? Dit is een pragmatische volgorde:
- Begin met een aparte databaseserver - de snelste winst met de minste complexiteit
- Voeg Redis toe als gedeelde object cache - alle servers profiteren direct
- Zet een tweede webserver op met identieke WordPress-installatie
- Configureer gedeelde uploads - start met S3-compatibele opslag
- Plaats een load balancer ervoor - begin met round robin
- Richt geautomatiseerde deployments in - zodat updates op alle servers tegelijk landen
- Implementeer monitoring en health checks - zodat je problemen ziet voordat je bezoekers ze merken
Veelgestelde vragen
Wanneer heb ik een multi-server setup nodig voor WordPress?
Zodra je merkt dat één server niet meer voldoende is om je verkeer op te vangen, je TTFB stijgt bij piekverkeer, of je uptime-eisen zo hoog zijn dat downtime van één server niet acceptabel is. Typisch vanaf tienduizenden bezoekers per dag of bij bedrijfskritische sites.
Kan WordPress op meerdere servers tegelijk draaien?
Ja, maar niet zonder aanpassingen. Je moet uploads centraal opslaan (bijvoorbeeld via NFS of S3), sessies delen via Redis of de database, en een load balancer inrichten die verkeer verdeelt. WordPress zelf is hier niet standaard op gebouwd.
Wat is het verschil tussen horizontaal en verticaal schalen?
Verticaal schalen betekent een krachtigere server inzetten (meer CPU, RAM). Horizontaal schalen betekent meerdere servers toevoegen die samen het verkeer afhandelen. Horizontaal schalen biedt betere redundantie en is op termijn flexibeler.
Heb ik een aparte databaseserver nodig?
Bij een multi-server setup wel, ja. Alle webservers moeten dezelfde database bereiken. Een dedicated databaseserver (of managed database zoals Amazon RDS) voorkomt resource-concurrentie met PHP en geeft je betere mogelijkheden voor tuning en replicatie.
Wat kost een multi-server WordPress setup?
De kosten variëren sterk. Een basissetup met twee webservers, een load balancer en een managed database begint rond de 100 tot 200 euro per maand bij cloudproviders. De complexiteit zit vooral in configuratie en onderhoud, niet alleen in serverkosten.