...

Server-CPU-benchmarking for PHP: Test af reelle webhosting-arbejdsbelastninger

En enkelt CPU-score er ikke nok til at vurdere en servers ydeevne i forhold til PHP. Kombiner en reproducerbar PHP-mikrobenchmark med en HTTP-test af din applikation: På den måde kan du sammenligne en konkret beregningsopgave og samtidig overvåge svartider, effektiv gennemstrømning og fejl under belastning. En webhosting-benchmark tager også højde for databasen, cachen og PHP-FPM. Dens procespool kan begrænse antallet af forespørgsler, uden at CPU’en alene udgør flaskehalsen. Det er afgørende, at forholdene er sammenlignelige, og at der efterfølgende foretages en diagnose.

Hvad en PHP-benchmark skal give svar på

En PHP-CPU-benchmark kan først og fremmest vise, hvor lang tid et system bruger på en bestemt beregningsopgave. Det er især nyttigt, når en enkelt forespørgsel bruger meget tid på PHP-beregninger. En højere Ydeevne med én kerne kan forkorte behandlingstiden for sådanne opgaver; man kan dog ikke ud fra en enkelt CPU-værdi udlede responstiden for et helt websted.

Et andet spørgsmål vedrører applikationens adfærd ved samtidige adgangsforespørgsler: Hvor mange korrekte svar leverer den pr. sekund, og hvor længe skal brugerne vente? Til dette formål er der en Webhosting-sammenligning via HTTP giver god mening. Den registrerer forløbet gennem webserveren og PHP samt eventuelt databasen, cachen og netværket. Netop denne kombination gør den praksisorienteret, men forhindrer en isoleret vurdering af CPU’en.

Det tredje spørgsmål drejer sig om flaskehalsen. Hvis en forespørgsel f.eks. afventer en databaseforespørgsel, siger en hurtigere beregning ikke meget om dens samlede varighed. Også en cache påvirker resultatet: Hvis en side allerede er leveret fuldt ud, før PHP træder i kraft, måler opkaldet ikke udførelsen af den dynamiske applikation.

Ved parallel belastning kan PHP-FPM-puljen desuden begrænse, hvor mange anmodninger der behandles samtidigt. Dens statusside giver blandt andet oplysninger om optagede processer og ventende anmodninger. En voksende kø er derfor en anledning til at foretage en diagnose, ikke et direkte bevis på, at CPU’en er for langsom.

Når man skal vælge en hostingudbyder, er det en hjælp at betragte disse spørgsmål hver for sig: først den sammenlignelige arbejdsenhed, derefter anvendelsen ved lav og høj belastning og til sidst de ressourcer, der begrænser resultatet. Hvordan CPU, RAM og lagerplads generelt spiller sammen, forklares i artiklen om Hardware til højtydende webhosting.

At skelne mellem CPU-resultater og programtests

En Mikrobenchmark gentager en lille, præcist defineret opgave. Med PHPBench kan man for eksempel undersøge en funktion til databehandling under fastlagte betingelser. Resultatet er nyttigt til at sammenligne denne funktion og dens kørselsmiljø; det beskriver hverken automatisk en komplet forespørgsel eller ydeevnen for et CMS eller en webshop.

Et AI-genereret symbolbillede af en udbygget serverprocessor på en antistatisk underlag
AI-genereret illustrativt billede: En mikrobenchmark undersøger en opgave på det testede system, ikke hele webstakken.

En HTTP-applikationstest besvarer et andet spørgsmål: Hvordan reagerer den valgte applikation via den faktisk anvendte webstack? Den tager for eksempel højde for PHP-FPM, databasen og cacher, i det omfang de indgår i det testede opkald. Den er er derfor velegnet til at vurdere et hostingtilbud, men kan ikke alene påvise, hvilken komponent der er årsag til en forskel.

SPEC CPU supplerer sådanne tests med standardiserede, beregningsintensive arbejdsbelastninger. SPEC CPU 2026 indeholder integer- og floating-point-suiter samt resultater for hastighed og gennemstrømning. Hastighed henviser til den tid, det tager at udføre opgaverne, mens gennemstrømning henviser til den samlede mængde data, der behandles. En hastighedsværdi er ikke nødvendigvis en ren single-core-værdi: SPEC påpeger yderligere parallelitet i heltal-hastighedstestene i 2026-suiten.

For at kunne foretage en pålidelig SPEC-sammenligning skal testsuiten, måleparameteren og resultattypen base eller peak stemmer overens. Det fuldt testede system er ligeledes afgørende: Ud over processoren har blandt andet hukommelse, kompilator og konfiguration indflydelse på resultatet. Offentliggjorte værdier er derfor ikke en isoleret egenskab ved CPU-modellen og kan ikke erstatte en PHP-test.

SPEC CPU 2017 og CPU 2026 anvender forskellige testsuiter; deres tal kan ikke sammenlignes på samme skala. Hvis man foretager en forudgående udvælgelse, bør man derfor sammenligne den fulde resultatrapport i stedet for en forkortet rangliste. Om en kandidat er egnet til ens egen anvendelse, viser først en passende udført anvendelsestest.

Fastlægge sammenlignelige testbetingelser

En retfærdig sammenligning starter med den samme applikationsversion og et sammenligneligt datasæt. Også den valgte rute og det forventede svar skal stemme overens: En produktside med mange databaseadgange besvarer et andet spørgsmål end en simpel API-funktion. Kontroller derfor ikke kun, om der kommer et svar, men også om indholdet passer til den påtænkte opgave.

Notér både PHP-versionen og udvidelserne samt webserveren, PHP-FPM-konfigurationen og databasen. Netværksstien mellem belastningsgeneratoren og applikationen skal også medtages i protokollen. Forskellige stier eller databaseplaceringer kan påvirke den målte responstid, selvom PHP-udførelsen ville være lige så hurtig på begge systemer.

Det er særligt vigtigt at skelne mellem CLI og PHP-FPM: En test fra kommandolinjen undersøger ikke automatisk den samme kørselskonfiguration som en HTTP-anmodning. Dokumenter de faktisk anvendte OPcache- og JIT-indstillinger for begge sammenhænge. Deres virkning og standardindstillinger afhænger blandt andet af PHP-versionen; en generel antagelse er ikke tilstrækkelig til sammenligningen.

Den Cache-tilstand skal være sammenlignelig. En kold cache og en cache, der allerede er opvarmet, giver svar på forskellige spørgsmål; begge kan være relevante, men bør analyseres hver for sig. Det samme gælder datamængde og testdata: Hvis arbejdsomfanget ændrer sig, kan en tidsforskel ikke længere entydigt tilskrives systemet.

Notér desuden CPU-modellen, de tildelte vCPU’er og de synlige ressourcebegrænsninger samt den valgte belastning og antallet af gentagelser. Hvis man bevidst sammenligner to forskellige hostingpakker, giver resultatet et billede af deres respektive samlede konfiguration. Forskelle i processor, begrænsninger, database eller caching må derfor ikke alene tolkes som en CPU-fordel uden yderligere diagnose.

Vælg passende arbejdsbelastninger og måleparametre

Valget af test afhænger af det spørgsmål, du ønsker at få besvaret. En Mikrobenchmark undersøger en begrænset beregningsopgave; en HTTP-test tager højde for vejen gennem webstakken. SPEC-resultater supplerer sammenligningen med standardiserede CPU-intensive systemtests, men erstatter ikke en test af den egne PHP-applikation.

Tre testtyper og deres begrænsninger
TesttypeBudskab og anvendelseDen vigtigste grænse
PHP-mikrobenchmarkSammenligner udførelsen af en bestemt PHP-funktion under fastlagte betingelser.Resultatet gælder i første omgang kun for den testede kode og kørselstiden.
SPEC CPUSammenligner systemer på baggrund af standardiserede, beregningskrævende opgaver; hastighed og hastighedsrate tager højde for forskellige aspekter.Dette er ikke en test af PHP-webhosting; vær opmærksom på Suite og den fulde systemkonfiguration.
HTTP-applikationstestTjekker svarstider og gennemstrømning for en endepunkt via den valgte webstack.Resultatet består af flere komponenter og isolerer ikke CPU’en.

For en enkelt dynamisk forespørgsel vælger du en repræsentativ side eller API-rute og starter med lav parallelitet. Ruten skal rent faktisk udføres af PHP: Et svar, der udelukkende leveres fra en forudgående sidecache, ville ganske vist være en gyldig cache-test, men siger ikke meget om PHP-behandlingen.

Ved samtidige besøgende tester du det samme slutpunkt ved flere fastlagte belastningsniveauer. På den måde kan du se, om svartiderne og den vellykkede gennemstrømning ændrer sig i takt med stigende parallelitet. Ved en databasekrævende rute bør datamængden, databasens placering og cache-tilstanden forblive uændret mellem sammenligningskørslerne.

En CPU-krævende funktion i applikationen kan du desuden undersøge isoleret ved hjælp af PHPBench, f.eks. en databehandling uden netværksadgang. Et bedre resultat viser i første omgang kun en fordel for denne funktion under de valgte kørselsbetingelser. Om dette medfører en mærkbar fordel for en hel side, må applikationstesten vise.

Udfør en staging-test med wrk

Test kun i et isoleret testmiljø med udtrykkelig tilladelse. Opret en ufarlig, repræsentativ læserute, og brug passende testdata. Fastlæg inden start en maksimal belastning samt afbrydelseskriterier, f.eks. fejl, timeouts eller forstyrrelser af andre tjenester.

Følgende kommando er beregnet til en terminal på en lokal staging-instans, der udtrykkeligt er konfigureret til dette formål. Den forberedte rute skal være tilgængelig på port 8080; kommandoen skaber faktisk belastning og er ikke beregnet til et ukendt eller produktivt system.

Terminal
wrk -t2 -c4 -d30s --latency http://127.0.0.1:8080/

Opkaldet bruger to belastningsgenerator-tråde, fire åbne forbindelser og har en varighed på 30 sekunder. Indstillingen --latency anmoder om en detaljeret oversigt over ventetider. Fire forbindelser er her valgt som udgangspunkt for dette eksempel og udgør ikke en generel anbefaling med hensyn til antallet af besøgende eller en servers kapacitet.

Den almindelige percentiludskrift fra wrk indeholder dog ikke en p95. For at opnå en reproducerbar p95-analyse skal du gemme følgende Lua-script på belastningsgeneratoren som percentiles.lua. Den angiver p50 og p95 fra latenstidsstatistikken i mikrosekunder; når man deler med 1.000, får man millisekunder.

Kode
function done(summary, latency, requests)
  io.write(string.format("p50: %.0f us\n", latency:percentile(50.0)))
  io.write(string.format("p95: %.0f us\n", latency:percentile(95.0)))
end

Start den samme lokale staging-test med scriptet for at udføre den egentlige måling. Filstien gælder for en terminal i den mappe, hvor scriptfilen ligger. Også denne kørsel skaber belastning; dokumentér de to udskrevne percentiler sammen med fejl og den separat kontrollerede svar kvalitet.

Terminal
wrk -t2 -c4 -d30s --latency -s percentiles.lua http://127.0.0.1:8080/

Planlæg en separat Opvarmningsfase før du registrerer de egentlige målinger. Gentag derefter hvert fastlagt belastningsniveau, og varier om muligt rækkefølgen af sammenligningssystemerne. Notér, hvor længe opvarmningen varede, og om cachen var i den ønskede tilstand ved målingens start.

Forøg antallet af forbindelser kun inden for de aftalte grænser, og kontroller afbrydelseskriterierne efter hvert trin. Hold også øje med belastningsgeneratoren: Hvis den selv er fuldt udnyttet, kan den begrænse resultatet. Kontroller desuden statuskoder og svarindhold; en hurtigt leveret fejlside eller et forkert svar tæller ikke som en vellykket applikationsanmodning.

Dokumentere belastningsniveauer og resultater

En måleprotokol knytter tallene sammen med de betingelser, under hvilke de er opstået. Noter for hvert kørsel omgivelserne, slutpunktet, cache-tilstanden og belastningsniveauet sammen med resultaterne. Følgende skema bruger blandt andet værdier, som wrk henholdsvis FPM-statussiden stiller til rådighed; du skal selv supplere med en indholdsmæssig kontrol af svarene.

Måleprotokol for en HTTP-kørsel
FeltHvad der registreres
OmgivelserServer eller hostingpakke, PHP- og applikationsversion samt relevant konfiguration
Arbejdsbelastning og cacheRute, testdata, svarkontrol og cache-status
Sidste trinBelastningsmodel, forbindelsestal eller foruddefineret forespørgselsfrekvens, varighed og opvarmningsfase
Vellykkede forespørgslerKorrekte svar pr. sekund; statuskoder og indhold skal kontrolleres separat
ForsinkelseMedian og p95 for samme kørsel; udskrives ved kørsel via det viste Lua-script
FejlFejlmeddelelser og timeouts
Oplysninger om ressourcerCPU-udnyttelse og, i det omfang det er tilgængeligt, FPM-processtatus og kø

Medianen angiver midtpunktet for de observerede svartider. Det p95 er den værdi, som 95 procent af de målte svar ikke overstiger. Tilsammen viser disse to størrelser, om der ud over en typisk forespørgsel også sker ændringer i den langsommere del af fordelingen. Fortolk dem altid sammen med fejl og timeouts.

Skel mellem et fast antal forbindelser og en forudbestemt forespørgselsfrekvens. Ved en forbindelsesbaseret test som i eksemplet kan langsomme svar medføre, at der genereres færre nye forespørgsler pr. sekund via de samme forbindelser. Den målte latenstid beskriver da ikke umiddelbart adfærden ved en uændret høj ankomstfrekvens.

Sammenlign derfor kun tilstrækkeligt ens belastningspunkter: samme rute og svarkontrol, sammenlignelige cache-tilstande samt samme belastningsmodel og samme belastningsniveau. En lav p95-værdi ved lav parallelitet kan ikke umiddelbart sammenlignes med en p95-værdi under overbelastning. Rapporter flere kørsler og deres spredning i stedet for at angive en enkelt gunstig værdi som resultat.

Undersøgelse af FPM og ressourcebegrænsninger

Hvis både køen og p95-svaretiden stiger i takt med den stigende belastning, er det en god idé at se nærmere på PHP-FPM-puljen. Sammenlign de aktuelle værdier for active processes, idle processes og listen queue med den konfigurerede øvre grænse pm.max_children. Hvis alle tilladte processer er aktive, ingen er ledige, og der er ventende anmodninger, tyder det på en Poolgrænse eller arbejdere, der har været beskæftiget i lang tid, men ikke nødvendigvis på en for langsom CPU.

AI-genereret illustration af skiver, der venter foran begrænsede åbninger i en procespool
AI-genereret illustration: Optagede processer kan forårsage ventende anmodninger, uden at det kan bevises, at CPU’en er årsagen.

Annoncen max children reached derimod viser, at procesgrænsen er blevet nået tidligere siden poolens start. Dette beviser i sig selv hverken, at der er en aktuel kø, eller at alle eksisterende processer er i gang lige nu. Ligeledes betyder det maksimale antal eksisterende processer ikke, at alle er aktive.

Workere kan også vente på databaseforespørgsler eller andre eksterne tjenester. Sammenlign derfor poolstatus og CPU-udnyttelse med de observerede svartider: En fuld kø ved lav CPU-udnyttelse tyder på, at man først bør undersøge ventetiderne og workernes udnyttelse. Et større antal pools er ikke automatisk løsningen, da yderligere processer også kræver ressourcer.

FPM-statusværdierne gælder for den pågældende pool; tællerne nulstilles ved en genstart. Notér derfor poolen og tidspunktet for genstart i måleprotokollen, og sammenlign tællerstande kun inden for et passende tidsrum. Beskyt en aktiveret statusside mod uautoriseret adgang, da den afslører driftsoplysninger om poolen.

Ved VPS og shared hosting betyder en tildelt vCPU ikke nødvendigvis en eksklusiv fysisk kerne. Hvor cgroup-v2-data er tilgængelige, viser cpu.max den konfigurerede begrænsning af CPU-båndbredden; cpu.stat kan blandt andet tælle for Neddrosling indeholdt. Ændringer af disse tællere under et kørsel hjælper med at diagnosticere en effektiv begrænsning.

Kontroller om muligt også overordnede cgroups: En grænse, der er indstillet der, kan påvirke den tilgængelige regnetid, selvom den umiddelbart synlige konfiguration virker generøs. Ikke alle tællere afspejler arvede begrænsninger fuldt ud. Hvis disse oplysninger mangler i hostingpakken, er den begrænsede synlighed udtrykkeligt en del af begrænsningerne i analysen.

At opdage spredning og fejlmålinger

En enkelt testkørsel kan give et tilfældigt gunstigt eller ugunstigt billede. Gentag de samme belastningsniveauer på dokumenterede tidspunkter, og varier om muligt rækkefølgen af sammenligningssystemerne. Især når ressourcerne deles, kan den tilgængelige ydeevne svinge; rapporter derfor ud over et typisk resultat også den observerede spredning og antallet af løb.

Sørg for, at gentagelserne bruger den samme cache-tilstand og det samme datasæt. En kørsel med en opvarmet side- eller databasecache kan ikke umiddelbart sammenlignes med en kold kørsel. Hvis et tilsyneladende hurtigere svar udelukkende stammer fra en sidecache, siger det ikke meget om, hvor hurtigt PHP udfører det dynamiske arbejde.

En CLI-mikrobenchmark er heller ikke et FPM-resultat: Den kører i en anden eksekveringskontekst og kan anvende andre OPcache- eller JIT-indstillinger. Dokumenter de faktisk aktive indstillinger for begge runtime-miljøer hver for sig, i stedet for at udlede dem ud fra PHP-versionen. En fordel i mikrotesten behøver ikke at vise sig i samme omfang i applikationens HTTP-test.

Medregn kun indholdsmæssigt korrekte, vellykkede svar i den vellykkede gennemstrømning. Hurtige fejlsider eller timeouts kan ellers forvride en sammenligning betydeligt. Ved markante afvigelser bør du også kontrollere ventetider i databasen, ændringer i cachen og synlige ressourcebegrænsninger, før du udelukkende tilskriver forskellen til CPU’en.

Das Taktadfærd kan ligeledes bidrage til spredningen. Hvilken frekvensregulering der er hensigtsmæssig, afhænger af platformen og belastningen; en generel indstilling kan ikke erstatte en sammenligning under de samme betingelser. Bidraget til CPU-regulator på hosting-servere forklarer sammenhængene med henblik på en mere indgående gennemgang.

Brug resultaterne til at vælge hosting

Ved forespørgsler, der hovedsageligt er CPU-intensive, er Tid pr. arbejdsenhed et vigtigt udvælgelseskriterium. Sammenlign derfor en repræsentativ PHP-funktion med dokumenteret køretid, og kontroller derefter, om fordelen også viser sig ved den dynamiske HTTP-rute. En mikrobenchmark beskriver i første omgang kun den testede kode, ikke hele hostingtilbuddet.

Hvis du forventer mange samtidige besøgende, er en hurtig enkeltforespørgsel ikke tilstrækkelig. Det er desuden afgørende, hvor mange korrekte svar pr. sekund systemet leverer ved et fastlagt belastningsniveau, og hvordan p95-latensen udvikler sig inden for det acceptable fejlinterval. Et system med højere gennemstrømning er ikke automatisk bedre til dit projekt, hvis dets langsomme svar overskrider kravene.

Ved database- eller cacheafhængige applikationer skal du vægte Anvendelsestest mere end en CPU-score. En typisk rute med et sammenligneligt datasæt viser, hvordan samspillet i stakken fungerer under de valgte betingelser. Et SPEC-resultat kan supplere forudvælgelsen, men beskriver et testet system og erstatter ikke en PHP-webhosting-test.

Før du foretager dit valg, skal du fastlægge, hvilke responstider, fejlprocenter og belastningsniveauer der er acceptable for applikationen. Sammenlign derefter kun resultater med en passende belastningsmodel og en sammenlignelig cache-tilstand. Du skal vurdere de forskellige hostingpakker som samlede konfigurationer; ud fra forskellen mellem dem kan CPU-andelen ikke udledes uden yderligere diagnose.

Beslutningen gælder for den målte tilstand, ikke for eventuelle senere versioner af applikationen eller spidsbelastninger. Gentag de relevante tests efter væsentlige ændringer i PHP, applikationen, databasen, cachen eller ressourcebegrænsningerne. På den måde kan du se, om de reserver, der tidligere var tilstrækkelige, stadig er til stede under de nye forhold.

Kilder og den aktuelle videnskabelige viden

Status for undersøgelsen:

Undersøgelses- og kildestatus: 4. november 2026. SPEC CPU 2017 og CPU 2026 er separate testsuiter; resultaterne gælder for det testede system og de dokumenterede betingelser.

https://phpbench.github.io/phpbench/

https://www.php.net/install.fpm.configuration

https://www.php.net/manual/en/fpm.status.php

https://spec.org/cpu2026/

https://www.spec.org/cpu2026/results/

https://spec.org/cpu2017/Docs/runrules.html

https://www.php.net/manual/en/opcache.configuration.php

https://github.com/wg/wrk/blob/master/README.md

https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v2.html?highlight=freezer

Aktuelle artikler

AI-genereret illustration af to sider med sammenlignelig opsætning på forskellige hostingplatforme
Wordpress

WordPress-benchmark: Reproducerbar test af hosting-ydeevne

En pålidelig WordPress-benchmark skelner mellem browseroplevelse, belastningsadfærd og hostingens indflydelse. På den måde kan du planlægge sammenlignelige målinger, kontrollere cache-tilstande og evaluere resultaterne uden at love en testvinder.