Deze PHP-handlervergelijking laat zien hoe mod_php, CGI, FastCGI, PHP-FPM en LSAPI de Prestaties van je hosting beïnvloeden – van CPU-belasting tot tail-latenties. Ik leg concreet uit welke keuze bij WordPress, WooCommerce en trafficpieken de Laadtijd verlaagt en tegelijkertijd hulpbronnen spaart.
Centrale punten
- PHP-FPM schaalt efficiënter dan mod_php en FastCGI.
- LSAPI levert de beste waarden op LiteSpeed.
- Isolatie per gebruiker verhoogt de veiligheid.
- OPcache en Redis verminderen latentie.
- P95/P99 toont echte gebruikerservaring.
Hoe PHP-handlers werken
Een PHP-handler verbindt de webserver met de interpreter en stuurt Processen, geheugen en I/O voor elke aanvraag. CGI start voor elke aanvraag een nieuw proces en laadt configuraties opnieuw, wat overhead veroorzaakt en de Latency verhoogd. Moderne varianten zoals FastCGI, PHP-FPM of LSAPI houden workers persistent beschikbaar en besparen zo opstarttijd, contextwisselingen en CPU-cycli. OPcache blijft in het geheugen, waardoor bytecode niet elke keer opnieuw hoeft te worden gecompileerd en dynamische pagina's sneller reageren. Tegelijkertijd bepaalt het procesbeheer hoeveel gelijktijdige verzoeken mogen worden uitgevoerd, hoe prioriteiten worden gesteld en hoe piekbelastingen kunnen worden opgevangen.
Directe vergelijking van de gangbare handlers
De keuze van de handler bepaalt de Schalen, het beveiligingsmodel en de RAM-behoefte van een toepassing. mod_php integreert PHP in het Apache-proces en levert korte responstijden, maar heeft te lijden onder zwakke Isolatie tussen accounts. CGI scheidt gebruikers netjes, maar kost veel CPU-tijd per verzoek. FastCGI vermindert de overhead, maar blijft minder efficiënt dan een goed afgestelde PHP-FPM. LSAPI doet er nog een schepje bovenop wanneer LiteSpeed wordt gebruikt en stabiliseert met name de tail-latenties bij veel gelijktijdige verbindingen.
| handelaar | Prestaties | Beveiliging | RAM-vereiste | Schaalbaarheid | Operationeel scenario |
|---|---|---|---|---|---|
| mod_php | Hoog | Laag | Laag | Medium | Kleine sites, zeldzame pieken |
| CGI | Laag | Hoog | Hoog | Laag | Statische inhoud, tests |
| FastCGI | Medium | Medium | Medium | Medium | tijdelijke oplossing |
| PHP-FPM | Zeer hoog | Hoog | Laag | Hoog | Shared hosting, CMS |
| LSAPI | Hoogste | Medium | Zeer laag | Zeer hoog | Veel verkeer, e-commerce |
PHP-FPM in de praktijk: processen, pools, tuning
PHP-FPM werkt met worker-pools die verzoeken uit een wachtrij halen en zo Pieken in belasting elegant opvangen. Ik stel voor elke website een eigen pool in, zodat configuratie, limieten en gebruikerscontext gescheiden blijven en de Beveiliging stijgt. In de praktijk zijn adaptieve instellingen zoals pm = dynamic of ondemand rendabel, omdat het aantal actieve processen zich aanpast aan de vraag. Het is van cruciaal belang dat pm.max_children en de tijdslimieten correct worden gedimensioneerd, zodat de wachtrij niet groeit en er toch RAM-reserves overblijven. Om te beginnen raad ik aan om de parameters op een gestructureerde manier te controleren; details over de fijnafstemming leg ik hier uit: PHP-FPM-procesbeheer.
LSAPI en LiteSpeed: topprestaties bij hoge gelijktijdigheid
LSAPI houdt PHP-processen in het geheugen en vermindert contextwisselingen, waardoor dynamische inhoud met HTTP/3 en QUIC nog soepeler worden geleverd. Onder volledige belasting blijft de P95/P99-latentie stabieler dan bij veel alternatieven, wat de Gebruikerservaring zichtbaar verbeterd. Ik zie regelmatig meer verzoeken per seconde en kortere TTFB op winkel- en inhoudspagina's, vooral wanneer OPcache en servercache samenwerken. Het voordeel komt niet alleen tot uiting in gemiddelde waarden, maar ook bij gelijktijdige sessies, sessies met cache-misses en „koude“ PHP-workers. Wie het verschil in architectuur wil begrijpen, leest het overzicht op LiteSpeed versus Nginx en beslist vervolgens over de stack.
WordPress en WooCommerce: meetwaarden correct interpreteren
Met WordPress bereik ik hoge scores met PHP 8.2 op FPM of LSAPI. req/s-waarden, terwijl WooCommerce door sessies, winkelwagenlogica en meer databasetoegang iets minder verzoeken per seconde verwerkt. De test wordt pas betekenisvol onder realistische omstandigheden. Verkeer gemengd met caching-hits en -misses. Critical CSS, objectcache en persistente verbindingen verleggen de grens waar vanaf er knelpunten ontstaan. Korte TTL's voor vaak gewijzigde inhoud en gedifferentieerde cache-keys voor taal, gebruikersstatus en apparaattype zijn bijzonder nuttig. Zo blijft de pagina snel, ook al levert deze gepersonaliseerde inhoud.
Beveiliging en isolatie: pools, gebruikerscontext, limieten
Ik geef de voorkeur aan aparte servers voor multi-user hosting. zwembaden per account, zodat rechten, paden en limieten netjes van elkaar gescheiden blijven. mod_php deelt een gemeenschappelijke context, wat het Risico verhoogd als een project hiaten vertoont. FPM of LSAPI met configuraties per gebruiker verminderen dit risico aanzienlijk, omdat processen onder de betreffende gebruiker draaien. Daarnaast is het mogelijk om verschillende php.ini-opties op projectniveau in te stellen, zonder andere sites te beïnvloeden. Resource-limieten zoals max_execution_time en memory_limit per pool voorkomen dat uitschieters de server vertragen.
Hulpbronnengebruik en RAM-planning
Elke PHP-worker neemt, afhankelijk van de code, uitbreidingen en OPcache-grootte aanzienlijk varieert, daarom meet ik het werkelijke gebruik in plaats van te gissen. Tools zoals ps, top of systemd-cgtop laten zien hoeveel RAM actieve workers werkelijk gebruiken en wanneer. Swapping dreigt. Daarna stel ik pm.max_children conservatief in, laat ik ruimte over voor de database, webserver en cacheservices en observeer ik de P95-latentie onder piekbelasting. Als er reserves overblijven, verhoog ik het aantal childs stapsgewijs en controleer ik opnieuw. Zo groeit de totale capaciteit op een gecontroleerde manier, zonder de server te overbelasten.
Meetmethode: van TTFB tot P99
Ik beoordeel niet alleen gemiddelde waarden, maar vooral P95– en P99-latenties, omdat ze de echte ervaring onder belasting weergeven. Een stack kan met identieke doorvoer werken en toch slechter presteren bij P99 als Wachtrijen groeien. Daarom test ik koude en warme caches, meng ik lees- en schrijfverzoeken en gebruik ik realistische concurrency-waarden. Zonder OPcache-warmup interpreteer ik resultaten voorzichtig, omdat veel systemen na een paar warmup-oproepen aanzienlijk sneller worden. Pas na representatieve testruns neem ik een beslissing over handlers, cachingstrategie en proceslimieten.
Beslissingsgids voor de keuze van de handler
Voor kleine sites met weinig logins volstaat mod_php of een zuinig FPM-Setup, mits veiligheidsaspecten worden aangepakt. Als de gelijktijdigheid toeneemt, schakel ik over naar PHP-FPM met aparte pools per project en activeer OPcache consequent. Bij sterk dynamische winkels en veel sessies geef ik de voorkeur aan LiteSpeed met LSAPI om P95 en P99 laag te houden. Wie om prijs- of architectuurredenen bij Apache/Nginx blijft, doet er goed aan om FPM goed af te stemmen. In alle gevallen telt de meting onder realistische omstandigheden meer dan benchmarks op een leeg systeem.
Praktische instellingen: caching, sessies, tijdslimieten
Ik zet in op OPcache met royale Geheugen-Allocatie, zodat bytecode zelden wordt verdrongen, en verplaats sessies indien mogelijk naar Redis, om bestandsvergrendelingen te voorkomen. Dit vermindert wachttijden bij gelijktijdige aanmeldingen en gepersonaliseerde pagina's. Voor externe diensten definieer ik duidelijke time-outs en circuitbreakers, zodat storingen niet het hele verzoek blokkeren. Op applicatieniveau houd ik cache-TTL's kort genoeg om actueel te blijven, maar lang genoeg voor een hoge hitratio. Wie regelmatig tegen worker-limieten aanloopt, vindt hier een startpunt: PHP-workers correct balanceren.
Kosten-batenanalyse en exploitatie
Ik beoordeel de Kosten een verandering ten opzichte van de meetbare winst in latentie, doorvoer en betrouwbaarheid. De overstap van FastCGI naar PHP-FPM levert vaak meer op dan een verandering van het subversienummer van PHP, omdat Proces-beheer en caching continu werken. LSAPI is vooral de moeite waard als LiteSpeed toch al wordt gebruikt en er veel gelijktijdige bezoekers zijn. Wie de stack omzet, moet de logs en statistieken nauwlettend volgen en rollback-paden voorbereiden. Een geplande A/B-operatie gedurende meerdere dagen levert de meest betrouwbare resultaten op.
Webserver-interactie: Apache-MPM, Nginx en Keep-Alive
In de praktijk is niet alleen de PHP-handler bepalend, maar ook de webservermodus. mod_php werkt met Apache in de prefork-MPM, maar blokkeert het gebruik van moderne eventmodellen. Wie HTTP/2, langere keep-alive-fasen en duizenden verbindingen efficiënt wil bedienen, kiest voor Apache. evenement + PHP-FPM of op Nginx/LiteSpeed als frontend. Het gevolg: het aantal benodigde PHP-workers is niet afhankelijk van het aantal TCP-verbindingen, maar van het daadwerkelijke tegelijkertijd lopende PHP-verzoeken. HTTP/2/3-multiplexing vermindert dus de overhead van de headers op de webserver, maar verandert niets aan te klein gedimensioneerde PHP-pools.
Nginx stuurt verzoeken doorgaans via FastCGI door naar FPM. Ik let op korte read_timeout- en send_timeout-waarden op de proxy, anders ontstaan er 502/504-fouten bij vastgelopen upstreams, hoewel PHP nog steeds werkt. In Apache-omgevingen beperk ik Keep-Alive zodanig dat lange inactieve verbindingen de threadpool niet blokkeren. LiteSpeed abstraheert veel hiervan, maar benut zijn voordeel pas volledig met LSAPI.
OPcache, JIT en preloading: wat echt helpt
OPcache is verplicht. In de praktijk dimensioner ik opcache.geheugen_verbruik ruim (bijv. 192–512 MB, afhankelijk van de codebasis) en verhoog opcache.max_versnelde_bestanden, zodat er geen evictions plaatsvinden. Voor builds die zelden worden geïmplementeerd, schakel ik validate_timestamps of zet een hogere opnieuw valideren_freq, om syscalls te besparen. Voorladen kan frameworks versnellen, maar heeft vooral effect bij een consistente autoload-structuur. Het JIT van PHP biedt bij klassieke webworkloads zelden voordelen en kan zelfs RAM kosten; ik schakel het alleen in als benchmarks onder reële omstandigheden dit bevestigen.
Wachtrijbeheer en terugdruk
De meeste knelpunten ontstaan niet in de CPU, maar in de wachtrij. Als er meer verzoeken binnenkomen dan er door de workers kunnen worden verwerkt, wordt de wachtrij langer en schiet de P95/P99-latentie omhoog. Ik zorg ervoor dat pm.max_kinderen groot genoeg is om typische pieken op te vangen, maar klein genoeg om RAM-reserve te behouden. pm.max_aanvragen stel ik gematigd in (bijv. 500-2000), zodat geheugenlekken geen langlopers veroorzaken. De listen.backlog moet passen bij de backlog van de webserver, anders verbreekt de kernel verbindingen onder belasting. Wie de aankomstfrequentie (verzoeken per seconde) en de gemiddelde servicetijd meet, kan met een eenvoudige capaciteitsberekening beoordelen vanaf welke gelijktijdigheid de latentie omkeert.
Time-outs, uploads en langlopers
Lange uploads of API-oproepen blokkeren werknemers. Ik stel duidelijke grenzen: max_uitvoering_tijd en verzoek_terminate_timeout in FPM voorkomen dat defecte verzoeken eindeloos blijven lopen. Op proxyniveau synchroniseer ik proxy_read_timeout/fastcgi_read_timeout met de FPM-limieten, zodat er geen voortijdige 504 optreedt. Grote uploads stream ik, beperk post_max_grootte en upload_max_filesize streng en plan speciale eindpunten, zodat de rest van het verkeer er niet onder lijdt. Voor cron-achtige langlopers verplaats ik het werk naar Cues of CLI-taken, in plaats van frontend-workers minutenlang te blokkeren.
Sessies en locking in detail
PHP-sessies zijn standaard blokkerend. Een tweede verzoek van dezelfde gebruiker wacht totdat de eerste de sessie vrijgeeft – fataal voor WooCommerce als er tegelijkertijd Ajax-oproepen lopen. Ik beëindig schrijftoegang tot sessies vroegtijdig met session_write_close(), zodra er geen mutaties meer nodig zijn. Met Redis als sessie-backend neemt de I/O-latentie af, maar locking-regels blijven belangrijk. Achter load balancers kies ik bewust tussen sticky sessions (eenvoudig, minder schaalbaar) en stateless patterns met objectcache, zodat horizontale schaalbaarheid goed werkt.
Bewaking en probleemoplossing
Zonder telemetrie is tuning een blinde vlucht. Ik activeer FPM-status en slowlogs per pool om knelpunten te zien en opvallende queries te identificeren.
; per pool pm.status_path = /status ping.path = /ping ping.response = pong request_slowlog_timeout = 3s slowlog = /var/log/php-fpm/www-slow.log pm.max_requests = 1000
Als er 502/504-fouten optreden, controleer ik eerst: is de FPM-wachtrij vol? Is er sprake van CPU-steal of swap? Komt de webserver-time-out overeen met de FPM-limieten? Een blik op smaps per werknemer toont de werkelijke RSS-bezetting, terwijl netstat/ss Backlog-overlopen opsporen. Voor OPcache houd ik de hitrate en het aantal hervalidaties in de gaten om evictions te voorkomen.
Containers, sockets en resource-limieten
In containers gebruik ik meestal TCP in plaats van Unix-sockets tussen webserver en FPM, om namespace-grenzen te vermijden en load-balancing te vergemakkelijken. Consistentie is belangrijk. cgroup-Limieten: als de container slechts 1-2 GB RAM heeft, moet pm.max_children dienovereenkomstig kleiner zijn, anders treedt de OOM-killer in werking. CPU-quota's hebben een grote invloed op de reactietijd; ik plan headroom en controleer de P95-latentie onder de limiet. NUMA- en core-affinity-kwesties worden relevant bij zeer hoge belasting, terwijl LSAPI in LiteSpeed-opstellingen veel hiervan intern optimaliseert.
Meerdere PHP-versies en uitbreidingen
Veel hosts draaien meerdere PHP-versies parallel. Ik isoleer pools per versie en houd Uitbreidingen slank. Elke extra module verhoogt het RAM-geheugen per worker en kan de opstarttijd verlengen. Ik verwijder consequent ongebruikte extensies; dat levert vaak meer op dan een kleine pm.max_children-toename. Bij de upgrade plan ik korte opwarmfasen voor OPcache in, zodat niet alle gebruikers na de implementatie tegelijkertijd een koude start meemaken.
Ram-dieet en realistische capaciteitsplanning
In plaats van forfaitaire waarden bepaal ik de gemiddelde en maximale RAM-behoefte per worker met live traffic. Daaruit leid ik af: (beschikbare RAM – systeem/DB/caches) / RAM per worker = maximale zinvolle pm.max_children. Daarnaast houd ik 15-25 % reserve voor burst, kernelcache en onvoorziene pieken. Als de toepassing sporadisch het geheugen opblaast, verlaag ik de limiet of verkort ik pm.max_requests om processen vaker te recyclen.
Teststrategie: reproduceerbare belasting en realistische patronen
Ik gebruik testprofielen die koude en warme caches combineren, GET/POST combineren en de gelijktijdigheid geleidelijk verhogen. Belangrijk: alleen met actieve OPcache en realistische denktijden kan ik zien of het systeem stabiel blijft onder gebruiksgedrag. Een ramp-up van enkele minuten voorkomt kunstmatige pieken bij de start. De evaluatie richt zich op TTFB en P95/P99, niet alleen op gemiddelde RTT of pure req/s.
Foutbeelden uit de praktijk
- Veel 504 onder piek: FPM-wachtrij vol, backlog te klein, time-outs op proxy korter dan in FPM.
- Stotteren bij deployments: OPcache-vervangingen, ontbrekende warm-up, te kleine opcache.memory_consumption.
- Goede gemiddelde waarden, slechte P99: te veel langlopende processen (I/O, externe API's), ontbrekende circuitbreakers.
- Hoge CPU, lage req/s: sessiesloten of niet-gecachete databasequery's die serieel beperken.
Bedrijfszekerheid en rollback
Elke wijziging aan de handler of de poolparameters voer ik uit met Feature vlaggen of stapsgewijs. Ik houd fout- en slowlogs, P95 en foutpercentages in de gaten en definieer een duidelijke terugkeer naar de oude situatie als de statistieken omslaan. Een tweede pool met identieke versie, maar andere parameters maakt een snelle A/B-wisseling mogelijk zonder downtime. Bij volledige belasting bewijst een korte, automatische vermindering van de concurrency (backpressure) zijn nut, in plaats van ongecontroleerd nieuwe workers te starten.
Kort samengevat
Voor dynamische sites met veel gelijktijdige gebruikers geef ik de voorkeur aan LSAPI op LiteSpeed, terwijl PHP-FPM op Apache of Nginx de beste Alleskunner mod_php blijft een speciaal geval voor zeer eenvoudige projecten zonder strikte isolatie. Realistische tests met warme OPcache, zinvolle pool-limieten en schone caching zijn doorslaggevend. Wie latentie betrouwbaar vermindert, meet P95/P99 en reageert eerst op tail-problemen in plaats van op gemiddelde waarden. Zo bereikt een applicatie merkbaar snellere antwoorden en meer reserves voor piekverkeer.


