Voor een zinvolle capaciteitsplanning van PHP-FPM bereken je eerst hoeveel workers er in het beschikbare RAM-budget passen. Los daarvan schat je hoeveel workers er nodig zijn voor het verkeer dat daadwerkelijk bij de pool binnenkomt. pm.max_kinderen beperkt het aantal workers dat tegelijkertijd per pool beschikbaar is, maar is noch een bezoekersaantal, noch een directe doorvoercapaciteit. Ook de CPU, de database en piekbelastingen bepalen welke instelling in de praktijk haalbaar is.
Wat een PHP-FPM-worker beperkt
PHP-FPM beheert PHP-processen in pools. Een Werknemer verwerkt telkens één aanvraag; de instelling van de pool pm.max_children beperkt het aantal tegelijkertijd beschikbare workers en daarmee het aantal PHP-verzoeken dat tegelijkertijd door deze pool wordt verwerkt. Bij meerdere pools geldt de limiet voor de betreffende pool, en niet automatisch voor de gehele server.
Dit getal is noch het aantal aangemelde bezoekers, noch een directe maatstaf voor het aantal verzoeken per seconde. Een bezoeker kan meerdere verzoeken genereren, terwijl een aangemelde gebruiker tussen twee acties in geen worker in beslag neemt. Omgekeerd kan één enkel traag verzoek een worker langer bezighouden dan meerdere korte verzoeken achter elkaar.
Ook komt niet elke pagina-oproep bij PHP-FPM terecht. Als de webserver een statisch bestand rechtstreeks levert of als een voorgeschakelde cache een verzoek volledig beantwoordt, is daarvoor – afhankelijk van de architectuur – geen PHP-worker nodig. Cache-misses, ingelogde gebruikers en beheerpagina’s kunnen daarentegen wel PHP-verzoeken genereren en de belasting tijdelijk verhogen.
Voor de capaciteitsplanning zijn daarom twee afzonderlijke vragen van cruciaal belang: hoeveel workers passen er, inclusief reserve, in het beschikbare RAM? En hoeveel workers zijn er nodig voor het verkeer dat daadwerkelijk bij de pool binnenkomt, zodat verzoeken niet buitensporig lang hoeven te wachten? Een hoge waarde voor pm.max_children beantwoordt geen van deze vragen afzonderlijk.
Zelfs als er voldoende geheugen beschikbaar is, kunnen de CPU, de database of externe diensten de praktische capaciteit beperken. Extra workers maken dan weliswaar meer parallelle PHP-verwerking mogelijk, maar kunnen tegelijkertijd de druk op een toch al trage dienst vergroten. De poolwaarde is daarom een operationele limiet en geen prestatiegarantie.
Procesbeheerder en wachtrij begrijpen
De Procesmanager bepaalt wanneer PHP-FPM workers beschikbaar stelt. Bij static komt het aangehouden procesgetal overeen met de waarde van pm.max_children. Hierdoor is het aantal processen goed te plannen, maar worden er ook bij een lage bezettingsgraad middelen vastgehouden. De bovengrens zelf moet wel in overeenstemming blijven met de beschikbare opslagruimte.
Op dynamic past FPM het aantal processen aan: het startaantal en het minimale en maximale aantal vrije workers worden bovendien ingesteld. Bij ondemand Workers worden pas aangemaakt wanneer dat nodig is en worden na een geconfigureerde inactiviteitstijd beëindigd. Dit kan bij zelden gebruikte pools middelen besparen; bij een plotselinge piek in de belasting moet er echter eerst nieuwe procescapaciteit worden gecreëerd.
| Modus | Belangrijke instellingen | Toepassing en afweging |
|---|---|---|
| statisch | pm.max_kinderen | Vast aantal werknemers; goed te plannen, maar middelen worden ongebruikt vastgehouden. |
| dynamisch | pm.max_children, pm.start_servers, pm.min_spare_servers, pm.max_spare_servers | Aanpassing aan veranderende behoeften; beschikbare en beginnende werknemers moeten op elkaar worden afgestemd. |
| ondemand | pm.max_children, pm.process_idle_timeout | Workers indien nodig; bespaart resources bij zelden gebruikte pools; bij een toename van de belasting moet rekening worden gehouden met het opstarten van processen. |
Als alle workers bezig zijn, kunnen verdere verzoeken in de Wachtrij voor luisteraars wachten op een vrij proces. De FPM-status geeft onder andere de huidige en de maximale wachtrij weer. Een enkele hoge maximumwaarde geeft echter niet aan of de pool op dat moment overbelast is; daarvoor is een tijdsreferentie nodig.
Een grotere wachtrij zorgt niet voor extra workers en versnelt een trage database niet. De wachtrij kan verzoeken tijdelijk opvangen, maar verschuift de wachttijd alleen maar naar vóór de PHP-verwerking. Voor de keuze van de procesmanager zijn daarom zowel het typische belastingsverloop als de gevolgen van korte pieken van belang.
Worker-geheugen correct indelen
Het geheugenverbruik van een worker kan niet op betrouwbare wijze worden afgeleid uit alleen een PHP-configuratielimiet. Voor de planning zijn procesgegevens onder passende belastingomstandigheden nuttiger. Daarbij maakt het verschil of je kijkt naar het resident geheugen van een enkel proces of dat je het verbruik van een hele groep PHP-FPM-workers wilt inschatten.
RSS beschrijft het resident geheugen van een proces. Als meerdere workers dezelfde geheugenpagina’s gebruiken, kunnen deze in hun respectievelijke RSS voorkomen. Als je de RSS-waarden van alle workers bij elkaar optelt, kunnen gedeelde pagina’s daardoor in sommige gevallen meerdere keren voorkomen; de som geeft daarom geen nauwkeurig beeld van het gezamenlijk bezette fysieke geheugen.
PSS verdeelt gedeelde pagina’s evenredig over de betrokken processen. De som van de PSS-waarden van een procesgroep is daarom vaak nuttiger voor de geheugenplanning dan de som van de RSS-waarden. Het blijft echter een momentopname: als het aantal processen dat pagina’s deelt verandert, veranderen ook de respectieve aandelen.
Bekijk meerdere workers bij zowel typische als geheugenintensieve verzoeken. Een pas gestart proces of een enkel gemiddelde kan de latere behoefte onderschatten. De totale pool-PSS bij verschillende aantallen workers en belastingstoestanden helpt bij het afleiden van een conservatieve schatting; een extrapolatie naar meer workers blijft onzeker vanwege variabele gemeenschappelijke en privé-aandelen.
Het PHP-memory_limit is geen betrouwbare indicatie voor het totale besturingssysteemgeheugen van een FPM-proces en vervangt deze waarneming niet. Gedeeld geheugen, bijvoorbeeld via OPcache, moet je niet zomaar een tweede keer van het budget aftrekken als het al proportioneel is opgenomen in de gebruikte pool-PSS. Er moet echter wel rekening worden gehouden met andere diensten en een reserve.
RAM-budget en aantal workers berekenen
Het uitgangspunt is het daadwerkelijk beschikbare RAM: op een host het geheugen dat bruikbaar is voor de diensten, in de container de effectieve geheugenlimiet. Trek daar de behoefte van het besturingssysteem, de webserver, een eventuele lokale database en andere diensten van af. Ook andere FPM-pools en een reserve voor schommelingen in het geheugengebruik moeten in de berekening worden meegenomen.
Het resterende deel is het Zwembadbudget. Voor de schatting van het aantal workers bekijk je de PSS-som van de pool-workers bij verschillende aantallen processen en belastingstoestanden. Houd daarbij rekening met zowel typische verzoeken als met eindpunten die veel geheugen verbruiken. Deel de betreffende som door het aantal workers in kwestie en leid uit meerdere waarnemingen een voorzichtige schatting af.
De volgende berekening is een illustratief rekenvoorbeeld, geen meting. De aangenomen waarden dienen uitsluitend om de rekenwijze te illustreren; ze vormen geen aanbeveling voor een specifieke toepassing. Het resultaat wordt afgerond op een geheel aantal workers.
| rekenstap | Acceptatie | Classificatie |
|---|---|---|
| Effectieve RAM-limiet | 4.096 MiB | Host- of containergrens in het voorbeeld |
| Overige diensten, pools en reserve | 2.048 MiB | Gezamenlijk overeengekomen aftrek |
| Begroting voor het betreffende zwembad | 2.048 MiB | 4.096 min 2.048 MiB |
| PSS-schattingswaarde per werknemer | 80 MiB | Aangenomen conservatieve planningswaarde |
| Rekenkundige RAM-limiet | 25 werknemers | 2.048 gedeeld door 80, afgerond |
De 25 workers vormen geen gegarandeerde, vaste toewijzing. PSS verdeelt gedeelde pagina’s proportioneel en deze verdeling verandert naargelang het aantal processen dat deze pagina’s deelt. Ook een andere mix van verzoeken kan de behoefte aan privégeheugen beïnvloeden; de schatting moet daarom worden getoetst aan het waargenomen totale verbruik en de bestaande limiet.
Als gedeeld geheugen, zoals OPcache, al proportioneel is opgenomen in het gebruikte PSS-totaal, trek je dit niet nogmaals forfaitair af als een volledige extra post. Houd echter wel rekening met een reserve voor geheugenaandelen die niet in je berekening zijn meegenomen. Juist bij een containerlimiet telt uiteindelijk het verbruik van alle processen binnen die limiet, niet alleen het geschatte aantal workers.
Een pas gestarte worker op zich zegt nog niet veel: deze heeft mogelijk nog geen veeleisend verzoek verwerkt. Vergelijk daarom meerdere tijdstippen en noteer welke eindpunten en hoeveel workers er telkens bij betrokken waren. Zo kun je zien of de gekozen benaderende waarde ook standhoudt bij minder gunstige, maar realistische bedrijfsomstandigheden.
Het aantal benodigde workers op basis van aanvragen inschatten
De RAM-berekening geeft aan hoeveel workers er naar verwachting in de pool kunnen worden ondergebracht. Voor de werkelijke behoefte telt daarentegen hoeveel PHP-verzoeken daadwerkelijk in de betreffende pool binnenkomen en hoe lang ze een worker bezighouden. Als eerste benadering geldt: het gemiddelde aantal gelijktijdig bezette workers is gelijk aan het aantal PHP-verzoeken per seconde, vermenigvuldigd met de gemiddelde bezettingstijd van een worker in seconden.
Illustratief rekenvoorbeeld, geen meting: uitgaande van 20 PHP-verzoeken per seconde en een gemiddelde verwerkingstijd van 0,25 seconde zijn er gemiddeld vijf workers bezig. Dit is een gemiddelde over de beschouwde periode. Dit betekent niet dat er altijd precies vijf processen actief zijn, noch dat vijf voldoende is als pool-limiet voor korte pieken.
Voor het aantal verzoeken mag je niet zomaar alle paginaweergaven meerekenen. Als een cache veel antwoorden levert zonder PHP aan te roepen, belasten deze treffers de pool niet. Omgekeerd kunnen cache-misses, ingelogde bezoekers en beheerderstoegang tijdelijk meer PHP-werk veroorzaken dan een gemiddelde over de hele dag doet vermoeden.
De Werknemersbezettingsduur omvat ook wachttijden tijdens de verwerking, bijvoorbeeld op een database of een externe dienst. Deze is niet automatisch gelijk te stellen aan de responstijd die in de browser wordt weergegeven. Volgens fastcgi_finish_request() kan PHP het antwoord al naar de client hebben verzonden en toch nog verdere taken in de worker uitvoeren.
Voor acceptabele wachttijden heb je een marge boven de gemiddelde bezettingsgraad nodig. Hoe groot die marge moet zijn, hangt onder andere af van belastingsschommelingen, trage eindpunten en de gewenste responstijddoelstelling. Het vermenigvuldigen van het aantal piekverzoeken per seconde met een hoog latentiepercentiel kan een voorzichtige scenario-check zijn, maar is geen nauwkeurige wachtrijprognose.
Bekijk daarom verschillende tijdsperioden afzonderlijk: een korte piek in de drukte en rustig nachtverkeer kunnen hetzelfde daggemiddelde opleveren als een gelijkmatiger verloop, maar stellen verschillende eisen. Als de bezettingsduur toeneemt door een trage backend, stijgt bij een gelijkblijvend aantal aankomsten ook het gemiddelde aantal gebonden workers. De behoefte is dus niet alleen afhankelijk van het bezoekersaantal.
Poolinstellingen afleiden uit de planning
Vergelijk nu de op RAM gebaseerde bovengrens met de geschatte behoefte, inclusief een marge. Als de behoefte daaronder ligt, kies dan een voorzichtige startwaarde voor pm.max_children, die het budget niet volledig hoeft te benutten. In het illustratieve voorbeeld zou 25 de theoretische RAM-limiet zijn, maar niet automatisch de juiste instelling; de CPU en de backend kunnen al eerder een limiet opleggen.
Als de geschatte behoefte boven de RAM-limiet ligt, lost een hogere limiet het probleem niet op: dit kan de host of container onder druk zetten wat betreft het geheugengebruik. Omgekeerd kan een zeer lage limiet ervoor zorgen dat verzoeken in de wachtrij terechtkomen. Verbeter in dat geval bijvoorbeeld de uitvoeringstijd of het cachegebruik en controleer of extra resources of een beperking van de inkomende belasting nodig zijn.
Op dynamisch Stel je naast de bovengrens ook het startaantal en het minimum- en maximumaantal vrije workers in. De start- en reservewaarden moeten aansluiten bij de verwachte belasting en binnen de bovengrens blijven. Te weinig gereserveerde capaciteit kan bij een plotselinge piek extra startbehoefte betekenen; daarentegen verbruiken permanent veel vrije processen resources.
Op ondemand Workers worden pas aangemaakt wanneer dat nodig is; de inactieve tijd totdat ze worden beëindigd, wordt apart ingesteld. Dit kan zinvol zijn voor pools die zelden worden gebruikt, maar vereist bijzondere aandacht bij snelle pieken in de belasting. Ook hier geldt dat pm.max_children het aantal workers uit de pool dat tegelijkertijd beschikbaar is.
Meerdere websites op dezelfde host krijgen niet elk afzonderlijk de volledige beschikbare RAM toegewezen. Bereken hun mogelijke poolmaxima samen met de overige diensten en de reserve. Een eventueel geconfigureerde globale FPM-proceslimiet kan aanvullend van toepassing zijn, maar vervangt noch de afzonderlijke poolbudgetten, noch de controle van de CPU- en databasecapaciteit.
Controleer na wijzigingen de daadwerkelijke belasting en wachttijden over geschikte periodes, in plaats van de startwaarde als definitief te beschouwen. Bij managed hosting zijn procesgegevens of poolinstellingen mogelijk niet direct toegankelijk; maak in dat geval gebruik van de statistieken en de door de provider vrijgegeven opties. Welke instellingen beschikbaar zijn, hangt bovendien af van de PHP-versie en de bedrijfsomgeving.
FPM-status en geheugen in de gaten houden
De FPM-statuspagina laat zien of de geplande workers voldoende zijn bij een werkelijke belasting. Beveilig het status-eindpunt buiten het bereik van het publiek: deze kan gevoelige gegevens over verzoeken en bronnen prijsgeven. Een afzonderlijk geconfigureerde status-listener kan ook bereikbaar blijven wanneer de hoofdpool overbelast is; controleer de beschikbaarheid en instellingen ervan voor jouw PHP-versie en webserverconfiguratie.
| Statuswaarde | Classificatie | Vervolgvraag |
|---|---|---|
| actieve processen / inactieve processen | Huidige werknemers en freelancers | Zijn er bij piekbelastingen nog vrije workers beschikbaar? |
| luisterwachtrij / maximale luisterwachtrij | Huidige en tot nu toe maximale wachtrijlengte | Wordt de wachtrij langer als de reactietijden langzaam zijn? |
| max. bereikte kinderen | Teller voor het bereiken van de limiet van het aantal workers bij ‘dynamic’ of ‘ondemand’ | Stijgt de teller in de betreffende periode? |
| langzame aanvragen | Teller voor trage verzoeken | Gaat deze stijging gepaard met langere responstijden? |
Beschouw de waarden als tijdreeksen samen met het aantal verzoeken en de responstijden. Een oud record van de wachtrij wijst niet op een huidige overbelasting; ook bij tellers is de stijging sinds de laatste waarneming veelzeggender dan de loutere totaalwaarde. Houd daarbij rekening met de start van de pool of herstarts, waardoor de referentieperiode verandert.
Voor een bekende FPM-worker kun je op een Linux-systeem met een beschikbare proc-interface geaggregeerde geheugenwaarden in leesmodus opvragen. Vervang PID met het daadwerkelijke proces-ID; je hebt hiervoor de juiste toegangsrechten nodig. Herhaal deze waarneming voor meerdere workers en belastingstoestanden, in plaats van uit één enkel proces een permanente poolgrootte af te leiden.
Trage verzoeken en wachtrijen onderzoeken
Een webshop kan veel actieve workers weergeven, ook al is de PHP-uitvoering zelf niet de oorspronkelijke bottleneck. Als verzoeken moeten wachten op trage databasequery's, blijven de workers ondertussen geblokkeerd. Als er nog meer verzoeken binnenkomen, kan de wachtrij van de listener groeien en de responstijd toenemen, zelfs als de CPU nog reserves heeft.
Een hogere limiet voor het aantal workers zorgt er in deze situatie mogelijk voor dat er meer verzoeken tegelijkertijd bij de database terechtkomen. Dat kan de Backend-afdrukken verhogen en de wachttijden nog verder verlengen. Vergelijk daarom het tijdsverloop van de FPM-bezettingsgraad en de wachtrij met de databasebelasting, trage zoekopdrachten en externe serviceaanroepen, voordat je de limiet verhoogt.
Het FPM-Slowlog helpt bij het opsporen van langdurige PHP-aanroepen: voor verzoeken die een geconfigureerde drempel overschrijden, kan FPM een backtrace vastleggen. Deze geeft een uitvoeringspunt weer en is geen volledig profiel van het gehele verzoek. Terugkerende punten kunnen worden vergeleken met de verzoekduur en backend-statistieken; de Handleiding voor het analyseren van het PHP-FPM-slowlog wordt in de verdere analyse toegelicht.
Ook een time-out moet worden onderscheiden van de daadwerkelijke capaciteit. Bij nginx wordt fastcgi_read_timeout de toegestane tijd tussen opeenvolgende leesbewerkingen van de FastCGI-server, niet de totale duur van het verzoek in het algemeen. Een hogere waarde kan een langere wachttijd toestaan, maar zorgt niet voor extra workers en versnelt de database ook niet.
Capaciteitsbeperkingen en volgende stappen
Als het RAM-budget niet toereikend is voor de geschatte behoefte, lost een hogere instelling voor pm.max_children Let niet op het doelconflict: extra processen hebben ook geheugen nodig. Controleer in plaats daarvan of het aantal PHP-verzoeken of de duur van de bezetting van de workers kan worden verminderd. Welke maatregel zinvol is, hangt af van waar de waargenomen belasting ontstaat.
Een beter benutte cache kan herhaalde verzoeken opvangen, terwijl een snellere PHP-uitvoering en database-toegang ervoor zorgen dat workers eerder worden vrijgegeven. Geschikte achtergrondtaken kunnen uit het directe verzoekpad worden verplaatst; ook deze taken hebben echter hun eigen resources nodig. Een belastingbeperking beschermt de backend tijdens pieken, maar kan ertoe leiden dat verzoeken moeten wachten of worden afgewezen.
Extra RAM kan een groter aantal workers mogelijk maken als het geheugen daadwerkelijk de beperkende factor is. Als de CPU, de database of een externe dienst al volledig benut worden, moet ook rekening worden gehouden met hun capaciteit. Meer geheugen alleen garandeert daarom noch kortere responstijden, noch een hogere doorvoersnelheid.
Als de opslagbehoefte van afzonderlijke workers tijdens hun levensduur toeneemt, kan pm.max_requests zorg ervoor dat deze regelmatig worden vervangen. Dit kan helpen bij het aanpakken van geheugenlekken in bibliotheken van derden, maar lost de oorzaak ervan niet op. Blijf na een wijziging het poolgeheugen en het verzoekgedrag in de gaten houden, in plaats van het herstartmechanisme te gebruiken als vervanging voor het opsporen van fouten.
Voor een bredere architecturale keuze biedt de Vergelijking tussen NGINX Unit en PHP-FPM Context: NGINX Unit is gearchiveerd en wordt niet meer onderhouden. Ongeacht de gekozen architectuur moet je wijzigingen doorvoeren op basis van tijdreeksen Controleer: vergelijk bij een vergelijkbaar aantal verzoeken de wachtrij, de bezettingsgraad van de workers, het geheugen en de responstijden. Zo kun je vaststellen of een aanpassing het knelpunt daadwerkelijk heeft verholpen of alleen maar heeft verplaatst.
Bronnen en stand van zaken op vakgebied
Stand van het onderzoek:
Stand van zaken: 4 november 2026. Controleer de beschikbaarheid van de status-listener, procesgegevens en pool-instellingen voor de gebruikte PHP- en Linux-versie en de hostingomgeving.
https://www.php.net/install.fpm.configuration
https://www.php.net/fpm.status.php
https://docs.kernel.org/7.0/filesystems/proc.html
https://www.kernel.org/doc/html/v6.12/filesystems/proc.html
https://www.php.net/manual/de/install.fpm.php
https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html



