...

NGINX FastCGI-cache: WordPress sneller maken

Ik maak WordPress merkbaar sneller door de NGINX-cache op serverniveau gebruik en HTML-antwoorden direct lever. Zo daalt de TTFB aanzienlijk, blijft PHP-FPM vrij en verwerkt de database minder Query's.

Centrale punten

  • Aan de serverzijde In plaats van een plug-in: FastCGI Cache ontlast PHP en vermindert de latentie.
  • Zuiveren bij wijzigingen: de inhoud blijft actueel en wordt gericht bijgewerkt.
  • Uitsluitingen Voor inloggen, het winkelmandje en afrekenen blijven dynamische gebieden dynamisch.
  • Schalen onder belasting: caches worden vaker geraadpleegd en verlagen de serverbelasting.
  • Meetbaar sneller: de TTFB-, RPS- en CPU-waarden verbeteren aanzienlijk.

Hoe de NGINX FastCGI-cache WordPress versnelt

Bij de eerste keer dat de pagina wordt opgevraagd, geeft WordPress de pagina weer; daarna slaat NGINX het voltooide antwoord op als HTML en verwerkt toekomstige identieke verzoeken zonder PHP-FPM. Zo verminder ik de CPU-tijd en het wisselen van context, terwijl het bestandssysteem of de OS-cache snelle Hits levert. Juist bij pieken blijft de responstijd laag, omdat er geen PHP-processen hoeven te worden gestart. Hierdoor minimaliseer ik de TTFB en maak ik meer verzoeken per seconde mogelijk. Het resultaat is een soepelere interactie, minder time-outs en een duidelijke prestatiereserve voor echt dynamische processen.

Cache aan de serverzijde versus cache via een plug-in (inclusief vergelijking)

Een cache-plug-in werkt in de PHP-stack en activeert vaak processen, zelfs bij treffers, terwijl FastCGI Cache direct op webserver-niveau reageert. Hierdoor vallen veel overheadkosten weg, zoals PHP-initialisatie en plugin-hooks. Voor terugkerende bezoekers vertrouw ik vooral op de serverzijde en combineer ik dit indien nodig met een lichte frontend-optimalisatieplugin. Wie de details grondig wil bekijken, begint met een gestroomlijnde Testfase en meet TTFB, CPU en cache-hit-rate afzonderlijk. De verschillen worden al snel zichtbaar – vooral onder belasting.

Criterium Plugin-cache (PHP) NGINX FastCGI-cache
Manier van beantwoorden PHP wordt geïnitialiseerd, de plug-in controleert de cache De webserver levert het bestand rechtstreeks aan
TTFB hoger door het opstarten van PHP zeer laag bij cache-treffers
Bronnen meer CPU/RAM per verzoek aanzienlijk minder hulpbronnen
Schalen beperkt door PHP-processen schaalbaar en efficiënt met NGINX
Afhankelijkheden Mogelijke conflicten tussen thema’s en plug-ins draait op WordPress

Daarnaast gebruik ik duidelijke cache-sleutels en een overzichtelijke mappenstructuur, zodat de inhoud per host, schema en URI gescheiden blijft. Wie op zoek is naar een introductie, kan mijn handleiding over de NGINX-cache-optimalisatie als leidraad gebruiken. Zo blijft de configuratie overzichtelijk en kunnen toekomstige uitbreidingen sneller worden doorgevoerd.

Geschikte scenario's en belangrijke uitzonderingen

Het meest geprofiteerd Inhoud, dus blogs, tijdschriften, landingspagina’s en bedrijfswebsites met veel anonieme bezoekers. Ik sla elke pagina op in de cache die voor bezoekers identiek blijft, en sluit alles wat gepersonaliseerd is uit. Hieronder vallen inlogpagina’s, profielen, reactieformulieren, de WooCommerce-winkelwagen, de kassa en ‘Mijn account’. Cookies en headers dienen als criterium om de cache doelgericht te omzeilen. Zo blijven openbare pagina’s razendsnel, terwijl gevoelige onderdelen correct dynamisch blijven en de gebruikers een soepele ervaring hebben. serveert worden.

Technische basisbegrippen: cachezone, sleutel, header

Ik definieer eerst de Cachepad en een zone in de NGINX-configuratie, inclusief grootte en inactiviteitstijd. De cache-sleutel bevat het schema, de host en de URI, en optioneel query-strings, zodat varianten apart worden opgeslagen. Via `fastcgi_cache_valid`, bypass- en no-cache-regels bepaal ik wanneer verzoeken de cache omzeilen. Belangrijke headers zoals Set-Cookie, Authorization en bepaalde cookies van WordPress of WooCommerce duiden op dynamiek. Daarnaast leg ik vast welke foutpagina’s of 50x-antwoorden kortstondig in de cache worden opgeslagen, zodat de pagina bij hoge belasting blijft antwoorden.

Cachebeheer en opschoningsstrategie

Een cache komt pas goed tot zijn recht als updates betrouwbaar zijn Uitrollen. Bij het opslaan van een bericht start ik een gerichte purge voor de betreffende URL’s, inclusief startpagina’s, categorieën en feeds. Daarnaast stel ik een zinvolle TTL in, zodat de inhoud periodiek opnieuw wordt gegenereerd. Bij grote websites helpt preload voor belangrijke landingspagina’s, zodat de eerste bezoeker geen ‘koude start’ ervaart. Na elke wijziging controleer ik de cache-hit-rate en of de opschoningen geen verouderde fragmenten achterlaten achterlaten.

Regels voor WordPress en WooCommerce

Ik laat ingelogde gebruikers consequent de cache gebruiken voorbij, meestal aan de hand van de cookie `wordpress_logged_in`. Voor WooCommerce sluit ik het winkelmandje, de kassa en ‘Mijn account’ uit via URI-patronen en let ik op cookies zoals `woocommerce_items_in_cart`. Product-, categorie- en inhoudspagina’s sla ik daarentegen gewoon op in de cache. Daarnaast verwijder ik de cache wanneer de voorraad of prijs via een hook verandert. Deze scheiding zorgt ervoor dat openbare pagina’s snel blijven, zonder dat aankoopprocessen worden storen.

De juiste keuze maken voor TTL, Stale en Locking

Ik stel de TTL van de inhoud in de praktijk in op bijvoorbeeld enkele minuten tot enkele uren, afhankelijk van Actualiteit en verkeer. Met ‘stale’-opties kan ik verouderde objecten tijdelijk leveren, terwijl er op de achtergrond een nieuwe versie wordt aangemaakt. Vergrendeling voorkomt het ‘stampede-effect’ wanneer veel verzoeken tegelijkertijd een verouderd object benaderen. Passende fout- en time-outregels zorgen ervoor dat bezoekers zelfs bij een korte storing een antwoord krijgen. Meer achtergrondinformatie over richtlijnen geef ik in mijn beknopte Cachebeheerstrategieën, die goed te combineren zijn met FastCGI Cache.

Monitoring en meetwaarden die ertoe doen

Ik meet eerst de TTFB, gevolgd door het aantal verzoeken per seconde en de CPU-belasting, uitgesplitst naar cache-hits en -misses. NGINX-logs en responsheaders laten me zien of er sprake is van een HIT, MISS, BYPASS of EXPIRED. Een stijgend hitpercentage bij een dalende CPU-belasting is voor mij het teken dat de regels werken. Daarnaast houd ik de I/O van het bestandssysteem en het aantal actieve PHP-processen in de gaten. Voor voorwaardelijke caching maak ik op een zinvolle manier gebruik van ETag/Last-Modified en verwijs ik naar mijn handleiding over Voorwaardelijke caching met ETag, zodat de cache van de browser en de server goed op elkaar zijn afgestemd en de netwerkbelasting merkbaar valt.

Veelvoorkomende fouten en hoe ik ze oplos

Een veelvoorkomend struikelblok is een te brede Cache-sleutel, die varianten overschrijft en verkeerde inhoud weergeeft. Eveneens kritiek: ontbrekende uitsluitingen voor cookies zoals wordpress_logged_in of WooCommerce-signalen. Als de opschoning alleen betrekking heeft op de afzonderlijke pagina, blijven archief- en startpagina’s verouderd; daarom breid ik de betreffende doelen uit. Ook query-strings heb ik vaak nodig in de sleutel, anders overschrijft de ene variant de andere. Te korte TTL’s veroorzaken onnodige MISS-percentages, te lange TTL’s verhogen het risico op verouderde Pagina's.

Praktische workflow voor de implementatie

Ik begin elk project met een duidelijk Plan: Doelen definiëren, te cachen paden markeren, dynamische uitzonderingen vastleggen. Vervolgens stel ik het cachepad, de zone, de sleutel en de headerregels in. In de volgende stap test ik HIT/MISS, controleer ik cookies en houd ik de TTFB in de gaten tijdens een lichte belastingstest. Vervolgens optimaliseer ik TTL, Stale en Locking totdat de grafieken er goed uitzien. Tot slot documenteer ik purge-routes, verantwoordelijkheden en een korte procedure voor redacteuren, zodat inhoud altijd vers blijven.

Praktische NGINX-configuratie en voorbeelden

Ik vind de configuratie duidelijk gestructureerd: een centrale cachezone, unieke sleutel, duidelijke skip-regels en nuttige diagnose-headers. Een solide uitgangspunt ziet er als volgt uit:

fastcgi_cache_path /var/cache/nginx levels=1:2 keys_zone=WORDPRESS:100m \
    inactive=60m use_temp_path=off loader_files=200 loader_sleep=50ms loader_threshold=300ms;

map $request_method $skip_non_get {
    default 1;
    GET 0;
    HEAD 0;
}

map $http_cookie $skip_cookie {
    default 0;
    ~*(wordpress_logged_in|comment_author|woocommerce_items_in_cart|wp_woocommerce_session|woocommerce_cart_hash) 1;
}

map $arg_preview $is_preview { standaard 0; 1 1; }
map $request_uri $is_search { standaard 0; ~*\?s= 1; }

server {
    # ...
    set $skip_cache 0;
    if ($skip_non_get) { set $skip_cache 1; }
    if ($skip_cookie)  { set $skip_cache 1; }
    if ($is_preview)   { set $skip_cache 1; }
    if ($is_search)    { set $skip_cache 1; }

    location ~ \.php$ {
 include fastcgi_params;
 fastcgi_pass unix:/run/php/php8.2-fpm.sock;

        fastcgi_cache WORDPRESS;
 fastcgi_cache_key "$scheme$request_method$host$request_uri";
 fastcgi_cache_bypass    $skip_cache;
        fastcgi_no_cache $skip_cache;

 fastcgi_cache_valid 200 301 302 10m;
        fastcgi_cache_valid 404 1m;
 fastcgi_cache_use_stale updating error timeout http_500 http_502 http_503;
 fastcgi_cache_lock on;
 fastcgi_cache_lock_timeout 5s;

        add_header X-Cache $upstream_cache_status always;
 add_header X-Cache-Key   $scheme$host$request_uri always;
    }
}

Ik breid dit later, afhankelijk van het project, uit met Vary-signalen (bijv. taal, valuta) en meer gedetailleerde uitsluitingen. Belangrijk: POST, PUT, DELETE en alles met Autorisatie of Set-Cookie Ik sla PHP consequent over.

Varianten- en cookiestrategieën in detail

Hoe minder varianten een HTML-document heeft, hoe hoger de hit-ratio. Ik beperk het aantal varianten bewust en maak alleen een onderscheid waar de Uitgave onderscheidt:

  • Taal: Eén enkele responsieve HTML-versie is ideaal. Als er aparte taalversies zijn, gebruik ik een taal-cookie of de URI (bijv. /de/, /en/) in de sleutel, niet de user-agent.
  • Apparaten: Ik vermijd UA-splitsingen. Mobile-first CSS en responsieve lay-outs houden de cache bij compact.
  • Valuta/Land: Bij webwinkels met geolokalisatie of een valutakeuzeschakelaar pas ik de instellingen doelgericht aan op basis van een stabiele cookie, niet op basis van het IP-adres. Anders loopt de cardinaliteit enorm op.
  • Query-reeksen: Ik zet nuttige parameters (bijv. paginering, filters) op de witte lijst en negeer trackingparameters (utm_*, gclid), zodat er geen overbodige varianten ontstaan.

Wees vooral voorzichtig met cookies van consent-/banner-plugins: als deze al op de startpagina cookies plaatsen, kan NGINX ten onrechte dynamische inhoud herkennen. Ik zorg ervoor dat puur visueel Banners zonder functionele gevolgen activeren geen cache-BYPASS-cascade.

Bestandssysteem, cachezone en loader-tuning

De keuze van het cachegeheugen heeft een enorme invloed op de prestaties. Ik gebruik snelle lokale SSD’s en ben van plan om de keys_zone ruim (bijv. 100–256 MB voor indexen), zodat metadata niet wordt verdrongen. De inactief‑Ik bepaal de tijd op basis van het verkeersprofiel: veel long-tail-content heeft baat bij een langere inactiviteit, terwijl dit voor zeer dynamische portalen meestal niet het geval is. Met loader_*-parameters regel ik hoe agressief NGINX objecten vooraf laadt – zodat het systeem onder belasting rustig blijft. Voor sites met zeer veel verkeer kan een deelcache in tmpfs zinvol zijn, maar ik controleer dan wel nauwkeurig de RAM-belasting en het inode-verbruik. Logrotatie en limieten voor het aantal bestanden voorkomen dat een volume vol raakt; de monitoring let op I/O-wachttijden, vrije ruimte en open-file-descriptoren.

CDN- en browsercache op de juiste manier indelen

Ik combineer de NGINX-cache graag met een Edge-CDN en solide TTL-waarden voor de browser. Hierbij geldt het volgende: de bron (NGINX) levert consistente HTML-pagina’s, het CDN slaat deze bovendien op in de cache, en de browser krijgt matig korte max-age-waarden, zodat redacteuren wijzigingen snel kunnen zien. Stale-mechanismen en revalidate‑Strategieën stel ik zo in dat Edge-knooppunten kunnen blijven leveren terwijl NGINX op de achtergrond opnieuw rendert. Purges activeer ik in een vastgestelde volgorde (eerst CDN, dan Origin) of synchroon op beide locaties, zodat er geen verouderde flanken ontstaan. Ik controleer bovendien of CDN-headers zoals Age, Cache-status en Vary niet in strijd zijn met mijn serverregels.

Voorverwarmen, implementatie en redactieworkflows

Om te voorkomen dat na een flush duizenden gebruikers de koude start activeren, warm ik belangrijke pagina’s op gericht voor: startpagina’s, bestsellers, categorieën, magazine-hubpagina’s. Een gestroomlijnde preloader leest de sitemap, roept pagina’s parallel op en houdt zich aan de rate limits, zodat noch PHP noch de database overbelast raken. Bij implementaties maak ik onderscheid tussen een volledige flush (wijziging van thema/code) en een gedeeltelijke flush (inhoudsupdate) en documenteer ik de Stappen voor de redactie en het operationele team. Zo blijven de release-periodes kort en zijn ze weinig risicovol.

Multisite, meertaligheid en valutalogica

Bij WordPress Multisite maak ik een strikt onderscheid tussen de cache-sleutels op basis van hostnaam of site-ID, zodat Subsites goed geïsoleerd zijn. Voor meertalige pagina’s met WPML/Polylang geef ik de voorkeur aan taalpaden (de/en) of speciale domeinen; de sleutel bevat dan het schema, de host en het pad. In webwinkels houd ik nauwkeurig rekening met valutacookies en geolokalisatie: ik sla product- en categoriepagina’s per valuta op in de cache, terwijl het winkelmandje en de kassa dynamisch blijven. Als prijzen of belastingtarieven veranderen, start ik een gedeeltelijk Verwijder (product, categorie, teaser-modules) zodat centrale startpagina's snel consistent zijn.

Belastingstesten, statistieken en rollback

Vóór de livegang simuleer ik realistische Pieken (GET/HEAD-mix, assets, HTML) en maak een strikt onderscheid tussen de metingen: warm versus cold, met/zonder CDN, ingelogde versus anonieme gebruikers. Ik kijk naar P50/P95-TTFB, foutpercentages, CPU-bezetting, I/O-wachttijd en het aantal PHP-processen. In NGINX activeer ik een geschikt log_format met $upstream_cache_status en controleer ik steekproeven direct in de responsheader (HIT/MISS/BYPASS/EXPIRED). Een kort rollback-traject (skip-schakelaar voor cachewerking, verkorte TTL, uitschakeling van afzonderlijke regels) zorgt ervoor dat ik bij afwijkingen onmiddellijk kan reageren zonder het totale systeem te destabiliseren.

Veiligheid, juistheid en gegevensbescherming

Ik zorg er consequent voor dat vertrouwelijke inhoud niet in de cache terechtkomt: beheerdersgedeelten, voorbeeldmodi, privépagina’s, met een nonce beveiligde acties. Ik houd me aan het onderscheid tussen HEAD en GET; POST blijft niet-cachebaar. Set-Cookie en Authorization gelden als harde BYPASS‑Signalen. Voorbeeldpagina’s (preview=true) en zoekresultaten (s=) laat ik buiten beschouwing, om te voorkomen dat er onjuiste resultaten worden weergegeven. Daarnaast controleer ik of er geen persoonsgegevens in HTML-antwoorden terechtkomen, die vervolgens op grote schaal in de cache zouden worden opgeslagen. Waar nodig kapsel ik gepersonaliseerde fragmenten in via afzonderlijke AJAX-eindpunten, die ik bewust niet cache.

Edge-cases en uitzonderingen correct afhandelen

Sommige patronen kom ik steeds weer tegen: XML-sitemaps en feed-eindpunten sla ik kort op in de cache (bijv. 1–5 minuten). 301/302-omleidingen valideer ik apart om omleidingslussen te voorkomen. Archief- en paginatiepagina’s krijgen gematigde TTL’s, omdat ze vaak links naar vers Inhoud bevatten. Parameters die alleen van invloed zijn op de sorteervolgorde, mogen in de sleutel worden opgenomen, maar mogen de TTL niet kunstmatig verkorten. En als een plug-in onverwacht cookies plaatst, controleer ik of deze echt nodig zijn voor de HTML-uitvoer relevant zijn – anders markeer ik ze als negeerbaar om onnodige BYPASS-treffers te voorkomen.

Kort samengevat

Met NGINX FastCGI Cache versnel ik WordPress aan de Bron, lever HTML direct aan en bespaar op dure PHP-processen. Nauwkeurige uitsluitingen en een betrouwbare purge houden de inhoud actueel, terwijl de TTFB- en CPU-waarden aanzienlijk dalen. Een praktijkgerichte TTL met stale en locking zorgt voor een soepele levering, zelfs bij piekbelastingen. Wie de meetwaarden consequent in de gaten houdt en de regels voortdurend aanscherpt, zorgt voor duurzaam snelle pagina’s. Zo wordt de website responsiever, blijft hij onderhoudsvriendelijk en groeit hij moeiteloos mee met stijgende Verkeer erin.

Huidige artikelen