Kennisbank › Vps Hosting › WordPress optimaliseren op een VPS
vps hosting gemiddeld 16 September 2026

WordPress optimaliseren op een VPS

Een WordPress-site die 912 ms doet over de eerste byte is geen WordPress-probleem maar een stack-probleem. Op een VPS heb je alle knoppen in handen om daar 178

Een WordPress-site die 912 ms doet over de eerste byte is geen WordPress-probleem maar een stack-probleem. Op een VPS heb je alle knoppen in handen om daar 178 ms van te maken, en dit artikel loopt de lagen langs waar dat gebeurt: webserver, PHP, database, cache en netwerk. Het is bedoeld voor wie al SSH-toegang heeft tot een eigen VPS en niet terugschrikt van een configuratiebestand.

De cijfers in dit stuk komen uit praktijkervaring en losse metingen, niet uit gecontroleerde benchmarks. Waar een percentage staat, staat er geen testomgeving naast. Behandel ze als richting, niet als belofte.

Vereisten

  • Een VPS met Ubuntu 22.04 LTS of 24.04 LTS, root of sudo-toegang via SSH.
  • Nginx 1.24 of hoger (de versie in de Ubuntu-repo's voldoet).
  • PHP 8.2 of 8.3 met PHP-FPM, plus de `php-fpm`- en `php-opcache`-pakketten.
  • MariaDB 10.11 of 11.4.
  • Een werkende WordPress-installatie die je al via Nginx bedient.
  • Redis 7.x als je object caching wilt toevoegen.
Mis je een van deze, zet eerst de basisstack op. Optimaliseren voor er iets draait is tijdverspilling.

Stappen

1. Zet Nginx klaar voor HTTP/2 en TLS 1.3

HTTP/2 multiplexed requests over één verbinding en TLS 1.3 scheelt een volledige round-trip bij de handshake. Op een VPS met weinig CPU merk je dat vooral bij veel gelijktijdige bezoekers.

```nginx server { listen 443 ssl; http2 on; server_name example.com;

ssl_protocols TLSv1.2 TLSv1.3; ssl_prefer_server_ciphers off; ssl_session_cache shared:SSL:10m; ssl_session_timeout 1d;

root /var/www/wordpress; index index.php index.html; } ```

TLS 1.2 laat je staan voor oudere clients. Alleen 1.3 aanzetten levert een paar milliseconden winst en een handvol boze bezoekers met een verouderde browser.

2. Zet Brotli-compressie aan

Brotli comprimeert tekstuele inhoud beter dan Gzip, zeker bij HTML en CSS. Het verschil loopt op tot zo'n 20 procent kleinere bestanden bij dezelfde content. De module zit niet standaard in de Ubuntu-pakketten, dus je compileert hem erbij of gebruikt de `libnginx-mod-http-brotli`-package als die beschikbaar is voor jouw versie.

```nginx brotli on; brotli_comp_level 5; brotli_types text/plain text/css application/javascript application/json image/svg+xml; ```

Compressieniveau 5 is het compromis. Niveau 11 wint een paar procent en kost je CPU die je op een kleine VPS harder nodig hebt.

3. Configureer de FastCGI page cache

Deze cache slaat complete HTML-pagina's op die PHP al heeft gegenereerd. Een volgende bezoeker krijgt het bestand direct van schijf in plaats van dat WordPress opnieuw opstart. Dit is de grootste sprong in TTFB die je op één avond kunt maken.

```nginx fastcgi_cache_path /var/cache/nginx/fastcgi levels=1:2 keys_zone=WORDPRESS:100m inactive=60m; fastcgi_cache_key "$scheme$request_method$host$request_uri";

server { set $skip_cache 0;

if ($query_string != "") { set $skip_cache 1; } if ($request_method = POST) { set $skip_cache 1; } if ($http_cookie ~* "wordpress_logged_in|comment_author|wp-postpass") { set $skip_cache 1; }

location ~ \.php$ { fastcgi_cache WORDPRESS; fastcgi_cache_valid 200 60m; fastcgi_cache_bypass $skip_cache; fastcgi_no_cache $skip_cache; fastcgi_pass unix:/run/php/php8.3-fpm.sock; include fastcgi_params; } } ```

De `skip_cache`-regels zijn niet optioneel. Zonder die uitzonderingen serveer je ingelogde gebruikers de pagina van een anonieme bezoeker, en dan zie je je eigen adminbalk verdwijnen. Caching is simpel tot je hem verkeerd scope't.

4. Stem PHP-FPM en OPcache af op je RAM

PHP-FPM beheert de processen die WordPress uitvoeren. Te weinig workers en requests staan in de wachtrij; te veel en je server gaat swappen. OPcache houdt gecompileerde PHP-scripts in het geheugen, wat herhaalde requests 30 tot 50 procent sneller maakt volgens praktijkervaring.

```ini ; /etc/php/8.3/fpm/pool.d/www.conf pm = dynamic pm.max_children = 20 pm.start_servers = 4 pm.min_spare_servers = 2 pm.max_spare_servers = 6 pm.max_requests = 500 ```

```ini ; /etc/php/8.3/fpm/conf.d/10-opcache.ini opcache.enable=1 opcache.memory_consumption=128 opcache.interned_strings_buffer=16 opcache.max_accelerated_files=10000 opcache.validate_timestamps=0 opcache.revalidate_freq=0 ```

`validate_timestamps=0` betekent dat PHP niet meer controleert of een scriptbestand is gewijzigd. Dat scheelt stat-calls per request. De prijs: na een plugin-update moet je `systemctl reload php8.3-fpm` draaien, anders blijft de oude code in het geheugen hangen.

Reken `pm.max_children` uit op je beschikbare RAM gedeeld door je gemiddelde PHP-procesgrootte. Op een VPS met 2 GB kom je met 20 kinderen meestal goed uit, maar meet het na een paar dagen met `ps` voordat je het als waarheid aanneemt.

5. Tunen van de MariaDB InnoDB buffer pool

De InnoDB buffer pool cachet data en indexen in het geheugen. Staat hij te klein, dan leest MariaDB bij elke query van schijf. Op een VPS waar de database en webserver hetzelfde RAM delen, is 70 tot 80 procent van het beschikbare geheugen te veel. Reserveer dat alleen als de database de enige zware bewoner is.

```ini

/etc/mysql/mariadb.conf.d/50-server.cnf

[mysqld] innodb_buffer_pool_size = 1G innodb_buffer_pool_instances = 2 innodb_log_file_size = 256M innodb_flush_method = O_DIRECT ```

Er is geen formule die voor elke site klopt. De buffer pool moet groot genoeg zijn voor je werkende dataset, niet voor je hele database. Een site met 50.000 posts waarvan er 200 per dag worden gelezen heeft meer aan een kleinere pool en meer vrij RAM.

6. Voeg Redis toe als object cache

WordPress voert bij elke pageload tientallen queries uit voor metadata, menu's en widgets. Redis vangt die op in het geheugen. In de praktijk zie je 60 tot 90 procent minder databasequeries, wat vooral merkbaar is op sites met veel plugins die elk hun eigen opties ophalen.

```bash sudo apt install redis-server php8.3-redis sudo systemctl enable --now redis-server ```

Installeer daarna de plugin Redis Object Cache via WP-CLI:

```bash wp plugin install redis-cache --activate wp redis enable ```

Redis draait standaard op poort 6379 op localhost. Zet hem niet open naar buiten, ook niet met een wachtwoord. Een open Redis is een van de snelste manieren om je VPS over te nemen.

7. Zet Cloudflare ervoor met APO

Een CDN verdeelt statische bestanden over servers dichtbij de bezoeker en ontlast je VPS. Cloudflare APO doet hetzelfde voor dynamische WordPress-pagina's, zodat je server-side FastCGI-cache niet in conflict komt met de edge-cache.

```bash

Controleer of Cloudflare je origin correct benadert

curl -sI https://example.com | grep -i cf-cache-status ```

De `cf-cache-status`-header vertelt je of een request uit de edge-cache kwam (`HIT`) of bij je VPS terechtkwam (`MISS`). APO is een betaalde dienst; de gratis Cloudflare-tier cachet alleen statische assets. Dat is een eerlijke afweging: gratis scheelt je bandbreedte, betaald scheelt je ook TTFB.

8. Zet BBR aan als TCP-congestie-algoritme

BBR meet actief de beschikbare bandbreedte in plaats van packet loss af te wachten zoals Cubic doet. Op verbindingen met hoge latentie — bezoekers buiten Europa, of mobiel verkeer — scheelt dat doorvoer.

```bash echo "net.core.default_qdisc=fq" | sudo tee -a /etc/sysctl.conf echo "net.ipv4.tcp_congestion_control=bbr" | sudo tee -a /etc/sysctl.conf sudo sysctl -p ```

Controleer daarna met `sysctl net.ipv4.tcp_congestion_control`. Staat er `bbr`, dan is het actief. Op een VPS met een dedicated NIC heeft het weinig zin; op een gedeelde virtuele NIC met variabele latentie wel.

Verificatie

Meet TTFB vanaf een externe locatie, niet vanaf de VPS zelf. Lokaal meten vertelt je niets over wat een bezoeker ervaart.

```bash curl -o /dev/null -s -w "TTFB: %{time_starttransfer}s\nTotal: %{time_total}s\n" https://example.com ```

Draai dit minstens drie keer en neem de mediaan. Eén meting is een toevalstreffer. Wis tussen tests je FastCGI-cache en de Cloudflare-cache, anders meet je de cache in plaats van de server.

Controleer daarnaast of OPcache daadwerkelijk draait:

```bash php -i | grep opcache.enable ```

En of Redis verbinding accepteert:

```bash redis-cli ping ```

Antwoordt Redis met `PONG`, dan leeft de service.

Veelgestelde problemen

Ingelogde gebruikers zien de verkeerde pagina. De `skip_cache`-regels in stap 3 dekken niet alle cookies. Voeg `wp_woocommerce_session` of je eigen sessiecookie toe aan de regex. Dit is bijna altijd een scope-fout, geen cachefout.

Wijzigingen aan een plugin komen niet door. `opcache.validate_timestamps=0` betekent dat PHP de bestanden niet opnieuw inleest. Draai `sudo systemctl reload php8.3-fpm` na elke codewijziging. Zet de waarde op `1` als je tijdens ontwikkeling vaak aanpast, en accepteer de tragere requests.

MariaDB gebruikt meer geheugen dan de buffer pool groot is. De buffer pool is niet de enige consument. Per connectie reserveert MariaDB sort- en join-buffers. Kijk met `SHOW VARIABLES LIKE 'max_connections'` en `SHOW STATUS LIKE 'Threads_connected'` of je niet te veel verbindingen openhoudt.

Wat dit kost

Elke laag die je toevoegt is een laag die kan omvallen. FastCGI-cache plus Redis plus Cloudflare APO betekent drie plekken waar een verkeerde configuratie je site stuk maakt zonder dat de foutmelding je vertelt welke. Begin bij de page cache en Redis, meet het effect, en voeg de rest pas toe als je weet wat je al hebt.

Zelf hosten op een VPS geeft je volledige controle over de stack. Het betekent ook dat er niemand anders is die om half twaalf 's avonds kijkt waarom MariaDB je geheugen opeet.

← Terug naar kennisbank
← Terug naar kennisbank