{"id":16053,"date":"2025-12-20T11:51:36","date_gmt":"2025-12-20T10:51:36","guid":{"rendered":"https:\/\/webhosting.de\/php-fpm-prozess-management-pm-max-children-optimieren-core\/"},"modified":"2025-12-20T11:51:36","modified_gmt":"2025-12-20T10:51:36","slug":"php-fpm-processtyring-pm-max-born-optimere-kerne","status":"publish","type":"post","link":"https:\/\/webhosting.de\/da\/php-fpm-prozess-management-pm-max-children-optimieren-core\/","title":{"rendered":"Korrekt konfiguration af PHP-FPM-processtyring: pm.max_children &amp; Co. forklaret"},"content":{"rendered":"<p><strong>php-fpm-optimering<\/strong> bestemmer, hvor mange PHP-FPM-processer der m\u00e5 k\u00f8re samtidigt, hvor hurtigt nye processer starter, og hvor l\u00e6nge de behandler foresp\u00f8rgsler. Jeg viser dig, hvordan du <strong>pm.max_b\u00f8rn<\/strong>, pm, pm.start_servers, pm.min_spare_servers, pm.max_spare_servers og pm.max_requests, s\u00e5 din applikation reagerer hurtigt under belastning, og serveren ikke g\u00e5r i swapping.<\/p>\n\n<h2>Centrale punkter<\/h2>\n\n<ul>\n  <li><strong>pm-tilstand<\/strong>: V\u00e6lg mellem static, dynamic eller ondemand, s\u00e5 processerne passer til din trafik.<\/li>\n  <li><strong>pm.max_b\u00f8rn<\/strong>: Tilpas antallet af samtidige PHP-processer til RAM og det reelle procesforbrug.<\/li>\n  <li><strong>Start-\/sparev\u00e6rdier<\/strong>: pm.start_servers, pm.min_spare_servers, pm.max_spare_servers p\u00e5 en fornuftig m\u00e5de.<\/li>\n  <li><strong>genanvendelse<\/strong>: Brug pm.max_requests til at afb\u00f8de hukommelsestab uden at skabe un\u00f8dvendig overhead.<\/li>\n  <li><strong>Overv\u00e5gning<\/strong>: Hold \u00f8je med logfiler, status og RAM, og juster derefter trin for trin.<\/li>\n<\/ul>\n\n<h2>Hvorfor processtyring er vigtig<\/h2>\n\n<p>Jeg styrer med <strong>PHP-FPM<\/strong> udf\u00f8relsen af hvert PHP-script som en separat proces, og hver parallel foresp\u00f8rgsel kr\u00e6ver sin egen worker. Uden passende begr\u00e6nsninger blokerer foresp\u00f8rgsler i k\u00f8er, hvilket f\u00f8rer til <strong>Timeouts<\/strong> og fejl. Hvis jeg s\u00e6tter lofterne for h\u00f8jt, spiser procespuljen al hukommelsen, og kernen begynder at <strong>swappen<\/strong>. Denne balance er ikke et g\u00e6tteri: Jeg baserer mig p\u00e5 reelle m\u00e5lev\u00e6rdier og holder en sikkerhedsmargen. P\u00e5 den m\u00e5de forbliver latenstiden lav og gennemstr\u00f8mningen stabil, selv n\u00e5r belastningen svinger.<\/p>\n\n<p>Det er vigtigt for mig, at der er en klar <strong>m\u00e5lv\u00e6rdi<\/strong>: Hvor mange samtidige PHP-udf\u00f8relser vil jeg tillade uden at udt\u00f8mme RAM? Samtidig kontrollerer jeg, om flaskehalse snarere opst\u00e5r i <strong>Database<\/strong>, i eksterne API'er eller p\u00e5 webserveren. Kun n\u00e5r jeg kender flaskehalsen, v\u00e6lger jeg de rigtige v\u00e6rdier for pm, pm.max_children og lignende. Jeg starter konservativt, m\u00e5ler og \u00f8ger derefter gradvist. P\u00e5 den m\u00e5de undg\u00e5r jeg h\u00e5rde genstarter og uventede nedbrud.<\/p>\n\n\n<figure class=\"wp-block-image size-full is-resized\">\n  <img fetchpriority=\"high\" decoding=\"async\" src=\"https:\/\/webhosting.de\/wp-content\/uploads\/2025\/12\/php-fpm-serveradmin-4912.png\" alt=\"\" width=\"1536\" height=\"1024\"\/>\n<\/figure>\n\n\n<h2>De tre pm-tilstande: static, dynamic, ondemand<\/h2>\n\n<p>Funktionen <strong>statisk<\/strong> holder altid n\u00f8jagtigt pm.max_children processer klar. Det giver meget forudsigelige ventetider, fordi der ikke er behov for nogen opstartsproces. Jeg bruger static, n\u00e5r belastningen er meget j\u00e6vn, og der er tilstr\u00e6kkelig RAM til r\u00e5dighed. Ved svingende eftersp\u00f8rgsel spilder jeg dog let i static. <strong>Hukommelse<\/strong>. Derfor bruger jeg static m\u00e5lrettet d\u00e9r, hvor jeg har brug for konstant udf\u00f8relse.<\/p>\n\n<p>Med <strong>dynamisk<\/strong> starter jeg en startm\u00e6ngde og lader poolst\u00f8rrelsen ligge mellem min_spare og max_spare. Denne tilstand er velegnet til trafik med b\u00f8lger, fordi arbejdere opst\u00e5r og oph\u00f8rer efter behov. Jeg holder altid nok inaktive processer til r\u00e5dighed til at h\u00e5ndtere spidsbelastninger uden ventetid. For mange inaktive arbejdere binder dog un\u00f8digt <strong>RAM<\/strong>, hvorfor jeg holder sparebel\u00f8bet lavt. P\u00e5 den m\u00e5de forbliver puljen fleksibel uden at svulme op.<\/p>\n\n<p>I tilstanden <strong>ondemand<\/strong> Der findes i f\u00f8rste omgang ingen arbejdere, PHP-FPM starter dem f\u00f8rst ved foresp\u00f8rgsler. Det sparer hukommelse i hvilefaser, men det f\u00f8rste hit koster lidt latenstid. Jeg v\u00e6lger ondemand til sj\u00e6ldent anvendte puljer, admin-v\u00e6rkt\u00f8jer eller cron-endepunkter. For meget bes\u00f8gte hjemmesider giver ondemand som regel d\u00e5rligere responstider. Der foretr\u00e6kker jeg klart dynamic med korrekt indstillede sparev\u00e6rdier.<\/p>\n\n\n<figure class=\"wp-block-image size-full is-resized\">\n  <img decoding=\"async\" src=\"https:\/\/webhosting.de\/wp-content\/uploads\/2025\/12\/phpfpm_konfiguration_9542.png\" alt=\"\" width=\"1536\" height=\"1024\"\/>\n<\/figure>\n\n\n<h2>Dimensioner pm.max_children korrekt<\/h2>\n\n<p>Det regner jeg med <strong>pm.max_b\u00f8rn<\/strong> fra den tilg\u00e6ngelige RAM til PHP og den gennemsnitlige hukommelse pr. worker. Til dette form\u00e5l reserverer jeg f\u00f8rst hukommelse til systemet, webserveren, databasen og caches, s\u00e5 systemet ikke g\u00e5r i <strong>Outsourcing<\/strong> k\u00f8rer. Jeg deler den resterende RAM med det reelt m\u00e5lte procesforbrug. Fra teorien tr\u00e6kker jeg 20-30 % sikkerhedsmargen for at udligne afvigelser og belastningsspidser. Jeg bruger resultatet som startv\u00e6rdi og observerer derefter effekten.<\/p>\n\n<p>Jeg beregner det gennemsnitlige procesforbrug med v\u00e6rkt\u00f8jer som <strong>ps<\/strong>, top eller htop og kigger p\u00e5 RSS\/RES. Vigtigt: Jeg m\u00e5ler under typisk belastning, ikke i tomgang. N\u00e5r jeg indl\u00e6ser mange plugins, frameworks eller store biblioteker, stiger forbruget pr. worker m\u00e6rkbart. Desuden begr\u00e6nser CPU'en kurven: Flere processer hj\u00e6lper ikke, hvis en <strong>Enkelt tr\u00e5d<\/strong>-CPU-ydeevne begr\u00e6nset pr. foresp\u00f8rgsel. Hvis du \u00f8nsker at dykke dybere ned i CPU-karakteristikken, finder du baggrundsinformation om <a href=\"https:\/\/webhosting.de\/da\/php-single-thread-performance-wordpress-hosting-hastighed\/\">Single-thread-ydeevne<\/a>.<\/p>\n\n<p>Jeg holder mine antagelser transparente: Hvor meget RAM har PHP reelt til r\u00e5dighed? Hvor stor er en worker ved typiske anmodninger? Hvilke spidsbelastninger opst\u00e5r der? Hvis svarene stemmer, indstiller jeg pm.max_children, foretager en bl\u00f8d genindl\u00e6sning og kontrollerer RAM, svartider og fejlrater. F\u00f8rst derefter g\u00e5r jeg videre i sm\u00e5 trin op eller ned.<\/p>\n\n<h2>Retningslinjer efter serverst\u00f8rrelse<\/h2>\n\n<p>F\u00f8lgende tabel giver mig <strong>Startv\u00e6rdier<\/strong> til r\u00e5dighed. Den erstatter ikke m\u00e5linger, men giver en solid vejledning til de f\u00f8rste indstillinger. Jeg tilpasser v\u00e6rdierne til hver enkelt anvendelse og kontrollerer dem med overv\u00e5gning. Hvis der er uudnyttede reserver, \u00f8ger jeg forsigtigt. N\u00e5r serveren n\u00e5r RAM-gr\u00e6nsen, tr\u00e6kker jeg v\u00e6rdierne tilbage.<\/p>\n\n<table>\n  <thead>\n    <tr>\n      <th><strong>Server-RAM<\/strong><\/th>\n      <th><strong>RAM til PHP<\/strong><\/th>\n      <th><strong>\u00d8 MB\/arbejder<\/strong><\/th>\n      <th><strong>pm.max_b\u00f8rn<\/strong> (Start)<\/th>\n      <th><strong>Brug<\/strong><\/th>\n    <\/tr>\n  <\/thead>\n  <tbody>\n    <tr>\n      <td>1\u20132 GB<\/td>\n      <td>~1 GB<\/td>\n      <td>50\u201360<\/td>\n      <td>15\u201320<\/td>\n      <td>Sm\u00e5 websteder, blogs<\/td>\n    <\/tr>\n    <tr>\n      <td>4\u20138 GB<\/td>\n      <td>~4\u20136 GB<\/td>\n      <td>60\u201380<\/td>\n      <td>30\u201380<\/td>\n      <td>Forretning, sm\u00e5 butikker<\/td>\n    <\/tr>\n    <tr>\n      <td>16+ GB<\/td>\n      <td>~10\u201312 GB<\/td>\n      <td>70\u201390<\/td>\n      <td>100\u2013160<\/td>\n      <td>H\u00f8j belastning, API, butikker<\/td>\n    <\/tr>\n  <\/tbody>\n<\/table>\n\n<p>Jeg l\u00e6ser tabellen fra h\u00f8jre mod venstre: Passer det <strong>Brug<\/strong> til projektet, kontrollerer jeg, om RAM er realistisk reserveret til PHP. Derefter v\u00e6lger jeg en worker-st\u00f8rrelse, der passer til kodebasen og udvidelserne. Derefter indstiller jeg pm.max_children og observerer effekten i live-drift. Tr\u00e6ffesprocenten og stabiliteten stiger, n\u00e5r jeg dokumenterer disse trin ordentligt.<\/p>\n\n\n<figure class=\"wp-block-image size-full is-resized\">\n  <img decoding=\"async\" src=\"https:\/\/webhosting.de\/wp-content\/uploads\/2025\/12\/php-fpm-prozessmanagement-5124.png\" alt=\"\" width=\"1536\" height=\"1024\"\/>\n<\/figure>\n\n\n<h2>Indstil start-, reserve- og anmodningsv\u00e6rdier<\/h2>\n\n<p>Med <strong>pm.start_servers<\/strong> Jeg fastl\u00e6gger, hvor mange processer der skal v\u00e6re klar med det samme. For lavt giver koldstart under belastning, for h\u00f8jt binder un\u00f8dvendigt RAM. Jeg g\u00e5r ofte efter 15\u201330 % fra pm.max_children og afrunder, hvis belastningen starter roligt. Ved trafikspidser v\u00e6lger jeg en lidt h\u00f8jere startm\u00e6ngde, s\u00e5 foresp\u00f8rgsler ikke ruller ind, f\u00f8r der er nok arbejdere, der venter. Denne finjustering reducerer den f\u00f8rste svartid betydeligt.<\/p>\n\n<p>V\u00e6rdierne <strong>pm.min_spare_servers<\/strong> og pm.max_spare_servers definerer inaktivitetsintervallet. Jeg holder s\u00e5 mange ledige arbejdere klar, at nye foresp\u00f8rgsler kan f\u00e5 direkte adgang, men ikke s\u00e5 mange, at inaktive processer spilder hukommelse. I butikker foretr\u00e6kker jeg at indstille et sn\u00e6vrere vindue for at udj\u00e6vne spidsbelastninger. Med <strong>pm.max_anmodninger<\/strong> Jeg genbruger processer efter nogle hundrede anmodninger for at begr\u00e6nse hukommelsesafvigelser. For ubetydelige applikationer v\u00e6lger jeg 500\u2013800, og hvis jeg har mistanke om l\u00e6kager, v\u00e6lger jeg bevidst et lavere tal.<\/p>\n\n<h2>Overv\u00e5gning og fejlfinding<\/h2>\n\n<p>Jeg tjekker regelm\u00e6ssigt <strong>Logfiler<\/strong>, status sider og RAM. Advarsler om n\u00e5ede pm.max_children-gr\u00e6nser er for mig et klart signal om at h\u00e6ve den \u00f8vre gr\u00e6nse eller optimere kode\/DB. Hvis 502\/504-fejl hober sig op, kigger jeg i webserverloggene og i k\u00f8erne. Markante udsving i latenstiden tyder p\u00e5 for f\u00e5 processer, blokerende I\/O eller for h\u00f8je procesomkostninger. Jeg ser f\u00f8rst p\u00e5 de h\u00e5rde fakta og reagerer derefter med sm\u00e5 skridt, aldrig med XXL-spring.<\/p>\n\n<p>Jeg opdager flaskehalse hurtigere, n\u00e5r jeg <strong>Ventetider<\/strong> m\u00e5le langs hele k\u00e6den: webserver, PHP-FPM, database, eksterne tjenester. Hvis backend-tiden kun stiger for bestemte ruter, isolerer jeg \u00e5rsagerne ved hj\u00e6lp af profilering. Hvis der opst\u00e5r ventetider overalt, ser jeg p\u00e5 server- og poolst\u00f8rrelsen. Det er ogs\u00e5 nyttigt at se p\u00e5 arbejdsk\u00f8er og processer i D-status. F\u00f8rst n\u00e5r jeg forst\u00e5r situationen, \u00e6ndrer jeg gr\u00e6nserne \u2013 og dokumenterer hver \u00e6ndring n\u00f8je.<\/p>\n\n\n<figure class=\"wp-block-image size-full is-resized\">\n  <img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/webhosting.de\/wp-content\/uploads\/2025\/12\/phpfpm_nachtarbeit_tech5982.png\" alt=\"\" width=\"1536\" height=\"1024\"\/>\n<\/figure>\n\n\n<h2>Webserver og PHP-FPM i samspil<\/h2>\n\n<p>Jeg s\u00f8rger for, at <strong>Webserver<\/strong>-Limits og PHP-FPM harmonerer. For mange samtidige forbindelser p\u00e5 webserveren med for f\u00e5 arbejdere for\u00e5rsager k\u00f8er og timeouts. Hvis arbejdstagerne er sat h\u00f8jt, men webserveren begr\u00e6nser accepten, forbliver ydeevnen lav. Parametre som worker_connections, event-Loop og Keep-Alive har direkte indflydelse p\u00e5 PHP-belastningen. En praktisk introduktion til finjustering findes i vejledningen til <a href=\"https:\/\/webhosting.de\/da\/threadpool-webserver-apache-nginx-litespeed-optimering-konfiguration\/\">Tr\u00e5dpuljer p\u00e5 webserveren<\/a>.<\/p>\n\n<p>Jeg beholder <strong>Keep-Alive<\/strong>-tidsvindue i kikkerten, s\u00e5 tomgangforbindelser ikke blokerer arbejdere un\u00f8digt. For statiske aktiver s\u00e6tter jeg aggressiv caching foran PHP for at holde arbejdsbyrden v\u00e6k fra puljen. Reverse-proxy-caches hj\u00e6lper desuden, n\u00e5r identiske svar ofte hentes. S\u00e5 kan jeg holde pm.max_children lavere og alligevel levere hurtigere. Mindre arbejde pr. foresp\u00f8rgsel er ofte den mest effektive justeringsskrue.<\/p>\n\n<h2>Fine justeringsskruer i php-fpm.conf<\/h2>\n\n<p>Jeg g\u00e5r ud over de grundl\u00e6ggende v\u00e6rdier og justerer <strong>Pool-parametre<\/strong> fint. Med <strong>pm.max_spawn_rate<\/strong> begr\u00e6nser jeg, hvor hurtigt nye arbejdere m\u00e5 oprettes, s\u00e5 serveren ikke starter processer for aggressivt ved belastningsspidser og glider ind i CPU-thrashing. For ondemand angiver jeg med <strong>pm.process_idle_timeout<\/strong> fast, hvor hurtigt ubrugte arbejdere forsvinder igen \u2013 for kort skaber startomkostninger, for lang binder RAM. Ved <strong>lytte<\/strong>-Socket v\u00e6lger jeg mellem Unix-Socket og TCP. En Unix-Socket sparer overhead og giver en klar tildeling af rettigheder via <em>listen.ejer<\/em>, <em>listen.gruppe<\/em> og <em>listen.mode<\/em>. For begge varianter s\u00e6tter jeg <strong>listen.backlog<\/strong> tilstr\u00e6kkelig h\u00f8j, s\u00e5 indkommende bursts ender i kernelbufferen i stedet for at blive afvist med det samme. Med <strong>rlimit_files<\/strong> hvis n\u00f8dvendigt \u00f8ger jeg antallet af \u00e5bne filer pr. worker, hvilket giver stabilitet ved mange samtidige uploads og downloads. Og hvis der er behov for prioriteter, bruger jeg <strong>procesprioritet<\/strong>, for at behandle mindre kritiske puljer lidt sekund\u00e6rt p\u00e5 CPU-siden.<\/p>\n\n<h2>Slowlog og beskyttelse mod h\u00e6ngninger<\/h2>\n\n<p>For at g\u00f8re langsomme anmodninger synlige aktiverer jeg <strong>Slowlog<\/strong>. Med <strong>request_slowlog_timeout<\/strong> definerer jeg den t\u00e6rskel (f.eks. 2\u20133 sekunder), hvorfra en stacktrace sendes til <strong>slowlog<\/strong> skrives. S\u00e5 finder jeg blokerende I\/O, dyre sl\u00f8jfer eller uventede l\u00e5se. Mod \u00e6gte h\u00e6ngere bruger jeg <strong>request_terminate_timeout<\/strong>, der afbryder h\u00e5rdt, hvis en anmodning k\u00f8rer for l\u00e6nge. Jeg holder disse tidsvinduer konsistente med <em>max_udf\u00f8relsestid<\/em> fra PHP og webserverens timeouts, s\u00e5 det ene lag ikke afbrydes f\u00f8r det andet. I praksis starter jeg konservativt, analyserer slowlogs under belastning og justerer t\u00e6rsklerne gradvist, indtil signalerne er meningsfulde uden at oversv\u00f8mme loggen.<\/p>\n\n<h2>Opcache, memory_limit og deres indflydelse p\u00e5 st\u00f8rrelsen af arbejdere<\/h2>\n\n<p>Jeg henviser til <strong>Opcache<\/strong> i min RAM-planl\u00e6gning. Dets delte hukommelsesomr\u00e5de t\u00e6ller ikke pr. arbejdstager, men deles af alle processer. St\u00f8rrelse og fragmentering (<em>opcache.memory_consumption<\/em>, <em>interned_strings_buffer<\/em>) har en betydelig indflydelse p\u00e5 opvarmningstiden og tr\u00e6fsikkerheden. En vel dimensioneret Opcache reducerer CPU- og RAM-belastningen pr. foresp\u00f8rgsel, fordi der skal kompileres mindre kode. Samtidig bem\u00e6rker jeg, at <strong>memory_limit<\/strong>: En h\u00f8j v\u00e6rdi beskytter mod hukommelsesmangel i enkelte tilf\u00e6lde, men \u00f8ger det teoretiske worst case-budget pr. worker. Derfor planl\u00e6gger jeg med et m\u00e5lt gennemsnit plus buffer, ikke med det rene memory_limit. Funktioner som preloading eller JIT \u00f8ger hukommelsesbehovet \u2013 jeg tester dem m\u00e5lrettet og indregner det ekstra forbrug i pm.max_children-beregningen.<\/p>\n\n<h2>Adskil og prioriter puljer<\/h2>\n\n<p>Jeg deler applikationer op <strong>flere pools<\/strong> n\u00e5r belastningsprofilerne er meget forskellige. En pool til frontend-trafik, en til admin\/backend, en tredje til cron\/uploads: S\u00e5dan isolerer jeg spidsbelastninger og tildeler differentierede gr\u00e6nser. For sj\u00e6ldent bes\u00f8gte slutpunkter indstiller jeg <em>ondemand<\/em> med kort idle-timeout for frontend <em>dynamisk<\/em> med sn\u00e6ver spare-margin. Om <strong>bruger\/gruppe<\/strong> og eventuelt. <em>chroot<\/em> Jeg s\u00f8rger for ren isolering, mens socket-rettigheder regulerer, hvilken webserverproces der har adgang. Hvor der er behov for prioriteter, f\u00e5r frontend mere <em>pm.max_b\u00f8rn<\/em> og eventuelt en neutral <em>procesprioritet<\/em>, mens Cron\/Reports k\u00f8rer med et mindre budget og lavere prioritet. P\u00e5 den m\u00e5de forbliver brugergr\u00e6nsefladen responsiv, selv n\u00e5r der k\u00f8rer tunge opgaver i baggrunden.<\/p>\n\n<h2>Brug statusendpunkter korrekt<\/h2>\n\n<p>For at diagnosticere l\u00f8betiden aktiverer jeg <strong>pm.status_path<\/strong> og valgfrit <strong>ping.path<\/strong> pr. pool. I status ser jeg Active\/Idle-Worker, der <em>Lister K\u00f8<\/em>, genneml\u00f8bsrelaterede t\u00e6llere og slow request-metrikker. En konstant voksende listek\u00f8 eller konstant 0 idle workers er for mig alarmsignaler. Jeg beskytter disse slutpunkter bag Auth og et internt netv\u00e6rk, s\u00e5 ingen driftsdetaljer kommer ud. Derudover aktiverer jeg <strong>catch_workers_output<\/strong>, hvis jeg hurtigt vil indsamle stdout\/stderr fra workerne \u2013 f.eks. ved fejl, der er sv\u00e6re at reproducere. Jeg kombinerer disse signaler med systemmetrikker (RAM, CPU, I\/O) for at beslutte, om jeg skal \u00f8ge pm.max_children, justere reservev\u00e6rdier eller \u00e6ndre applikationen.<\/p>\n\n<h2>S\u00e6rlige forhold i containere og VM'er<\/h2>\n\n<p>P\u00e5 <strong>Containere<\/strong> og sm\u00e5 VM'er tager jeg h\u00f8jde for cgroup-begr\u00e6nsninger og risikoen for OOM-killeren. Jeg indstiller pm.max_children strengt efter <em>Container-hukommelsesgr\u00e6nse<\/em> og tester belastningsspidser, s\u00e5 ingen arbejdere bliver lukket ned. Uden swap i containere er sikkerhedsmargenen s\u00e6rlig vigtig. Ved CPU-kvoter skalerer jeg antallet af arbejdere til det tilg\u00e6ngelige antal vCPU'er: hvis applikationen er CPU-bundet, medf\u00f8rer mere parallelitet snarere k\u00f8er end gennemstr\u00f8mning. IO-bundne arbejdsbelastninger t\u00e5ler flere processer, s\u00e5 l\u00e6nge RAM-budgettet holder. Derudover indstiller jeg <strong>emergency_restart_threshold<\/strong> og <strong>emergency_restart_interval<\/strong> til master-processen for at afv\u00e6rge en nedbrudsspiral, hvis en sj\u00e6lden fejl rammer flere b\u00f8rn p\u00e5 kort tid. P\u00e5 den m\u00e5de forbliver tjenesten tilg\u00e6ngelig, mens jeg analyserer \u00e5rsagen.<\/p>\n\n<h2>Problemfri implementeringer og genindl\u00e6sninger uden nedbrud<\/h2>\n\n<p>Jeg planl\u00e6gger <strong>Genindl\u00e6sninger<\/strong> s\u00e5ledes, at igangv\u00e6rende anmodninger afsluttes korrekt. En <em>elegant genindl\u00e6sning<\/em> (f.eks. via systemd reload) overtager nye konfigurationer uden at afbryde \u00e5bne forbindelser. Jeg holder socket-stien stabil, s\u00e5 webserveren ikke oplever forbindelsesafbrydelser. Ved versions\u00e6ndringer, der ugyldigg\u00f8r meget Opcache, forvarmer jeg cachen (preloading\/warmup-requests) for at begr\u00e6nse latenstoppe umiddelbart efter implementeringen. St\u00f8rre \u00e6ndringer tester jeg f\u00f8rst p\u00e5 en mindre pool eller i en Canary-instans med identisk konfiguration, f\u00f8r jeg ruller v\u00e6rdierne ud over hele linjen. Hver tilpasning ender med tidsstempel og metrik-sk\u00e6rmbilleder i min \u00e6ndringslog \u2013 det forkorter fejlfinding, hvis der er uventede bivirkninger.<\/p>\n\n<h2>Burst-adf\u00e6rd og ventek\u00f8er<\/h2>\n\n<p>Jeg udligner belastningsspidser med et afstemt <strong>K\u00f8design<\/strong> af. Jeg s\u00e6tter <strong>listen.backlog<\/strong> s\u00e5 h\u00f8j, at kernen kortvarigt kan buffe flere forbindelsesfors\u00f8g. P\u00e5 webserver-siden begr\u00e6nser jeg det maksimale antal samtidige FastCGI-forbindelser pr. pool, s\u00e5 de til <em>pm.max_b\u00f8rn<\/em> passer. S\u00e5ledes ophobes bursts hellere kortvarigt i webserveren (billigt) end dybt i PHP (dyrt). Jeg m\u00e5ler <em>Lister K\u00f8<\/em> i FPM-status: Hvis den stiger regelm\u00e6ssigt, \u00f8ger jeg enten antallet af arbejdere, optimerer cache-hitfrekvensen eller s\u00e6nker aggressive keep-alive-v\u00e6rdier. M\u00e5let er at undg\u00e5 <em>Tid til f\u00f8rste byte<\/em> at holde stabiliteten i stedet for at lade anmodninger forsvinde i endel\u00f8se k\u00f8er.<\/p>\n\n<h2>Praksis-workflow for tilpasninger<\/h2>\n\n<p>Jeg starter med en <strong>Revision<\/strong>: RAM-budget, processt\u00f8rrelse, I\/O-profiler. Derefter indstiller jeg konservative startv\u00e6rdier for pm.max_children og pm-tilstand. Derefter k\u00f8rer jeg belastningstests eller observerer reelle spidsbelastningstider. Jeg logger alle \u00e6ndringer sammen med m\u00e5linger og tidsvinduer. Efter hver justering kontrollerer jeg RAM, latenstid P50\/P95 og fejlrater \u2013 f\u00f8rst derefter g\u00e5r jeg videre til n\u00e6ste trin.<\/p>\n\n<p>N\u00e5r jeg gentagne gange n\u00e5r gr\u00e6nsen, eskalerer jeg ikke straks situationen. <strong>Arbejder<\/strong>-tal. F\u00f8rst optimerer jeg foresp\u00f8rgsler, cache-hitrater og dyre funktioner. Jeg flytter IO-tunge opgaver til k\u00f8er og forkorter svarveje. F\u00f8rst n\u00e5r applikationen fungerer effektivt, \u00f8ger jeg poolst\u00f8rrelsen. Denne fremgangsm\u00e5de sparer ressourcer og undg\u00e5r f\u00f8lgeskader andre steder.<\/p>\n\n\n<figure class=\"wp-block-image size-full is-resized\">\n  <img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/webhosting.de\/wp-content\/uploads\/2025\/12\/phpfpm_schreibtisch_7321.png\" alt=\"\" width=\"1536\" height=\"1024\"\/>\n<\/figure>\n\n\n<h2>Typiske scenarier: Eksempelv\u00e6rdier<\/h2>\n\n<p>P\u00e5 en 2 GB vServer reserverer jeg ca. <strong>1 GB<\/strong> for PHP-FPM og indstiller en worker-forbrug p\u00e5 ca. 50-60 MB. Dermed starter jeg med pm.max_children p\u00e5 15-20 og bruger dynamic med en lille startm\u00e6ngde. min_spare holder jeg p\u00e5 2-3, max_spare p\u00e5 5-6. pm.max_requests indstiller jeg p\u00e5 500, s\u00e5 processer udskiftes regelm\u00e6ssigt. Disse indstillinger giver sm\u00e5 projekter stabile reaktionstider.<\/p>\n\n<p>Med 8 GB RAM planl\u00e6gger jeg normalt 4\u20136 GB til <strong>PHP<\/strong> og indstiller arbejdstagerst\u00f8rrelser p\u00e5 60\u201380 MB. Dette resulterer i 30\u201380 underprocesser som startomr\u00e5de. pm.start_servers ligger p\u00e5 15\u201320, min_spare p\u00e5 10\u201315, max_spare p\u00e5 25\u201330. pm.max_requests v\u00e6lger jeg mellem 500 og 800. Under belastning kontrollerer jeg, om RAM-spidsbelastningen giver plads, og \u00f8ger derefter forsigtigt.<\/p>\n\n<p>I h\u00f8jbelastningsops\u00e6tninger med 16+ GB RAM reserverer jeg 10\u201312 GB til <strong>FPM<\/strong>. Med 70\u201390 MB pr. medarbejder ender jeg hurtigt med 100\u2013160 processer. Om statisk eller dynamisk er mest hensigtsm\u00e6ssigt, afh\u00e6nger af belastningsformen. Ved konstant h\u00f8j belastning er statisk det bedste valg, ved b\u00f8lgende eftersp\u00f8rgsel er dynamisk det bedste. I begge tilf\u00e6lde er konsekvent overv\u00e5gning et must.<\/p>\n\n<h2>Undg\u00e5 forhindringer og s\u00e6t prioriteter<\/h2>\n\n<p>Jeg forveksler ikke antallet af <strong>Bes\u00f8gende<\/strong> med antallet af samtidige PHP-scripts. Mange sidevisninger rammer caches, leverer statiske filer eller blokerer uden for PHP. Derfor dimensionerer jeg pm.max_children efter m\u00e5lt PHP-tid, ikke efter sessioner. Hvis processerne er sat for sparsomt, ser jeg ventende anmodninger og stigende fejlrater. Ved for h\u00f8je v\u00e6rdier tipper hukommelsen i swap, og alt bliver langsommere.<\/p>\n\n<p>En almindelig misforst\u00e5else: Flere processer er lig med mere <strong>Hastighed<\/strong>. I virkeligheden er det balancen mellem CPU, IO og RAM, der t\u00e6ller. Hvis CPU'en g\u00e5r op p\u00e5 100 % og latenstiden stiger kraftigt, hj\u00e6lper flere arbejdere n\u00e6ppe. Det er bedre at fjerne den reelle flaskehals eller reducere belastningen via cachen. Hvorfor arbejdere ofte er flaskehalsen, forklares i vejledningen til <a href=\"https:\/\/webhosting.de\/da\/php-workers-hosting-flaskehals-guide-balance\/\">PHP-Worker som flaskehals<\/a>.<\/p>\n\n\n<figure class=\"wp-block-image size-full is-resized\">\n  <img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/webhosting.de\/wp-content\/uploads\/2025\/12\/phpfpm-serverkonfig-7342.png\" alt=\"\" width=\"1536\" height=\"1024\"\/>\n<\/figure>\n\n\n<h2>Kort opsummeret<\/h2>\n\n<p>Jeg unders\u00f8ger f\u00f8rst den reelle <strong>RAM<\/strong>-forbruget pr. worker og indstiller pm.max_children med buffer. Derefter v\u00e6lger jeg pm-tilstanden, der passer til belastningsformen, og afbalancerer start- og reservev\u00e6rdier. Med pm.max_requests holder jeg processerne friske uden un\u00f8dvendig overhead. Logs, status og metrikker leder jeg ind i en ren overv\u00e5gning, s\u00e5 hver \u00e6ndring forbliver m\u00e5lbar. P\u00e5 den m\u00e5de opn\u00e5r jeg korte svartider, stabile puljer og en serverbelastning, der har reserver til spidsbelastninger.<\/p>","protected":false},"excerpt":{"rendered":"<p>Omfattende vejledning til php-fpm-tuning: L\u00e6r, hvordan du optimerer pm.max_children og andre procesparametre for at maksimere din php-performance-hosting.<\/p>","protected":false},"author":1,"featured_media":16046,"comment_status":"","ping_status":"","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_crdt_document":"","inline_featured_image":false,"footnotes":""},"categories":[780],"tags":[],"class_list":["post-16053","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administration-anleitungen"],"acf":[],"_wp_attached_file":null,"_wp_attachment_metadata":null,"litespeed-optimize-size":null,"litespeed-optimize-set":null,"_elementor_source_image_hash":null,"_wp_attachment_image_alt":null,"stockpack_author_name":null,"stockpack_author_url":null,"stockpack_provider":null,"stockpack_image_url":null,"stockpack_license":null,"stockpack_license_url":null,"stockpack_modification":null,"color":null,"original_id":null,"original_url":null,"original_link":null,"unsplash_location":null,"unsplash_sponsor":null,"unsplash_exif":null,"unsplash_attachment_metadata":null,"_elementor_is_screenshot":null,"surfer_file_name":null,"surfer_file_original_url":null,"envato_tk_source_kit":null,"envato_tk_source_index":null,"envato_tk_manifest":null,"envato_tk_folder_name":null,"envato_tk_builder":null,"envato_elements_download_event":null,"_menu_item_type":null,"_menu_item_menu_item_parent":null,"_menu_item_object_id":null,"_menu_item_object":null,"_menu_item_target":null,"_menu_item_classes":null,"_menu_item_xfn":null,"_menu_item_url":null,"_trp_menu_languages":null,"rank_math_primary_category":null,"rank_math_title":null,"inline_featured_image":null,"_yoast_wpseo_primary_category":null,"rank_math_schema_blogposting":null,"rank_math_schema_videoobject":null,"_oembed_049c719bc4a9f89deaead66a7da9fddc":null,"_oembed_time_049c719bc4a9f89deaead66a7da9fddc":null,"_yoast_wpseo_focuskw":null,"_yoast_wpseo_linkdex":null,"_oembed_27e3473bf8bec795fbeb3a9d38489348":null,"_oembed_c3b0f6959478faf92a1f343d8f96b19e":null,"_trp_translated_slug_en_us":null,"_wp_desired_post_slug":null,"_yoast_wpseo_title":null,"tldname":null,"tldpreis":null,"tldrubrik":null,"tldpolicylink":null,"tldsize":null,"tldregistrierungsdauer":null,"tldtransfer":null,"tldwhoisprivacy":null,"tldregistrarchange":null,"tldregistrantchange":null,"tldwhoisupdate":null,"tldnameserverupdate":null,"tlddeletesofort":null,"tlddeleteexpire":null,"tldumlaute":null,"tldrestore":null,"tldsubcategory":null,"tldbildname":null,"tldbildurl":null,"tldclean":null,"tldcategory":null,"tldpolicy":null,"tldbesonderheiten":null,"tld_bedeutung":null,"_oembed_d167040d816d8f94c072940c8009f5f8":null,"_oembed_b0a0fa59ef14f8870da2c63f2027d064":null,"_oembed_4792fa4dfb2a8f09ab950a73b7f313ba":null,"_oembed_33ceb1fe54a8ab775d9410abf699878d":null,"_oembed_fd7014d14d919b45ec004937c0db9335":null,"_oembed_21a029d076783ec3e8042698c351bd7e":null,"_oembed_be5ea8a0c7b18e658f08cc571a909452":null,"_oembed_a9ca7a298b19f9b48ec5914e010294d2":null,"_oembed_f8db6b27d08a2bb1f920e7647808899a":null,"_oembed_168ebde5096e77d8a89326519af9e022":null,"_oembed_cdb76f1b345b42743edfe25481b6f98f":null,"_oembed_87b0613611ae54e86e8864265404b0a1":null,"_oembed_27aa0e5cf3f1bb4bc416a4641a5ac273":null,"_oembed_time_27aa0e5cf3f1bb4bc416a4641a5ac273":null,"_tldname":null,"_tldclean":null,"_tldpreis":null,"_tldcategory":null,"_tldsubcategory":null,"_tldpolicy":null,"_tldpolicylink":null,"_tldsize":null,"_tldregistrierungsdauer":null,"_tldtransfer":null,"_tldwhoisprivacy":null,"_tldregistrarchange":null,"_tldregistrantchange":null,"_tldwhoisupdate":null,"_tldnameserverupdate":null,"_tlddeletesofort":null,"_tlddeleteexpire":null,"_tldumlaute":null,"_tldrestore":null,"_tldbildname":null,"_tldbildurl":null,"_tld_bedeutung":null,"_tldbesonderheiten":null,"_oembed_ad96e4112edb9f8ffa35731d4098bc6b":null,"_oembed_8357e2b8a2575c74ed5978f262a10126":null,"_oembed_3d5fea5103dd0d22ec5d6a33eff7f863":null,"_eael_widget_elements":null,"_oembed_0d8a206f09633e3d62b95a15a4dd0487":null,"_oembed_time_0d8a206f09633e3d62b95a15a4dd0487":null,"_aioseo_description":null,"_eb_attr":null,"_eb_data_table":null,"_oembed_819a879e7da16dd629cfd15a97334c8a":null,"_oembed_time_819a879e7da16dd629cfd15a97334c8a":null,"_acf_changed":null,"_wpcode_auto_insert":null,"_edit_last":null,"_edit_lock":null,"_oembed_e7b913c6c84084ed9702cb4feb012ddd":null,"_oembed_bfde9e10f59a17b85fc8917fa7edf782":null,"_oembed_time_bfde9e10f59a17b85fc8917fa7edf782":null,"_oembed_03514b67990db061d7c4672de26dc514":null,"_oembed_time_03514b67990db061d7c4672de26dc514":null,"rank_math_news_sitemap_robots":null,"rank_math_robots":null,"_eael_post_view_count":"2654","_trp_automatically_translated_slug_ru_ru":null,"_trp_automatically_translated_slug_et":null,"_trp_automatically_translated_slug_lv":null,"_trp_automatically_translated_slug_fr_fr":null,"_trp_automatically_translated_slug_en_us":null,"_wp_old_slug":null,"_trp_automatically_translated_slug_da_dk":null,"_trp_automatically_translated_slug_pl_pl":null,"_trp_automatically_translated_slug_es_es":null,"_trp_automatically_translated_slug_hu_hu":null,"_trp_automatically_translated_slug_fi":null,"_trp_automatically_translated_slug_ja":null,"_trp_automatically_translated_slug_lt_lt":null,"_elementor_edit_mode":null,"_elementor_template_type":null,"_elementor_version":null,"_elementor_pro_version":null,"_wp_page_template":null,"_elementor_page_settings":null,"_elementor_data":null,"_elementor_css":null,"_elementor_conditions":null,"_happyaddons_elements_cache":null,"_oembed_75446120c39305f0da0ccd147f6de9cb":null,"_oembed_time_75446120c39305f0da0ccd147f6de9cb":null,"_oembed_3efb2c3e76a18143e7207993a2a6939a":null,"_oembed_time_3efb2c3e76a18143e7207993a2a6939a":null,"_oembed_59808117857ddf57e478a31d79f76e4d":null,"_oembed_time_59808117857ddf57e478a31d79f76e4d":null,"_oembed_965c5b49aa8d22ce37dfb3bde0268600":null,"_oembed_time_965c5b49aa8d22ce37dfb3bde0268600":null,"_oembed_81002f7ee3604f645db4ebcfd1912acf":null,"_oembed_time_81002f7ee3604f645db4ebcfd1912acf":null,"_elementor_screenshot":null,"_oembed_7ea3429961cf98fa85da9747683af827":null,"_oembed_time_7ea3429961cf98fa85da9747683af827":null,"_elementor_controls_usage":null,"_elementor_page_assets":[],"_elementor_screenshot_failed":null,"theplus_transient_widgets":null,"_eael_custom_js":null,"_wp_old_date":null,"_trp_automatically_translated_slug_it_it":null,"_trp_automatically_translated_slug_pt_pt":null,"_trp_automatically_translated_slug_zh_cn":null,"_trp_automatically_translated_slug_nl_nl":null,"_trp_automatically_translated_slug_pt_br":null,"_trp_automatically_translated_slug_sv_se":null,"rank_math_analytic_object_id":null,"rank_math_internal_links_processed":null,"_trp_automatically_translated_slug_ro_ro":null,"_trp_automatically_translated_slug_sk_sk":null,"_trp_automatically_translated_slug_bg_bg":null,"_trp_automatically_translated_slug_sl_si":null,"litespeed_vpi_list":null,"litespeed_vpi_list_mobile":null,"rank_math_seo_score":null,"rank_math_contentai_score":null,"ilj_limitincominglinks":null,"ilj_maxincominglinks":null,"ilj_limitoutgoinglinks":null,"ilj_maxoutgoinglinks":null,"ilj_limitlinksperparagraph":null,"ilj_linksperparagraph":null,"ilj_blacklistdefinition":null,"ilj_linkdefinition":null,"_eb_reusable_block_ids":null,"rank_math_focus_keyword":"php-fpm tuning","rank_math_og_content_image":null,"_yoast_wpseo_metadesc":null,"_yoast_wpseo_content_score":null,"_yoast_wpseo_focuskeywords":null,"_yoast_wpseo_keywordsynonyms":null,"_yoast_wpseo_estimated-reading-time-minutes":null,"rank_math_description":null,"surfer_last_post_update":null,"surfer_last_post_update_direction":null,"surfer_keywords":null,"surfer_location":null,"surfer_draft_id":null,"surfer_permalink_hash":null,"surfer_scrape_ready":null,"_thumbnail_id":"16046","footnotes":null,"_links":{"self":[{"href":"https:\/\/webhosting.de\/da\/wp-json\/wp\/v2\/posts\/16053","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/webhosting.de\/da\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/webhosting.de\/da\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/webhosting.de\/da\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/webhosting.de\/da\/wp-json\/wp\/v2\/comments?post=16053"}],"version-history":[{"count":0,"href":"https:\/\/webhosting.de\/da\/wp-json\/wp\/v2\/posts\/16053\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/webhosting.de\/da\/wp-json\/wp\/v2\/media\/16046"}],"wp:attachment":[{"href":"https:\/\/webhosting.de\/da\/wp-json\/wp\/v2\/media?parent=16053"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/webhosting.de\/da\/wp-json\/wp\/v2\/categories?post=16053"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/webhosting.de\/da\/wp-json\/wp\/v2\/tags?post=16053"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}