Windows IIS FastCGI Spin-Up Performance Slowdown
- Dominant language
- C
- Stars
- 40.4k
- Forks
- 8.2k
- Avg merge
- 2d 13h
- Merged PRs (30d)
- 96
Description
Description
Default Form:
The following code:
<?php
$obj = array("loaded"=>microtime(true),"version"=>phpversion());
# Sleep in order to ensure new fastcgis spin up with provided Powershell Script.
sleep(2);
echo json_encode($obj);
?>
Resulted in this output:
2-3 times slower fastcgi spin up time versus older versions.
{"loaded":<epoch micro time>,"version":<php version>}
But I expected this output instead:
Similar FastCGI Spin up times to older versions
{"loaded":<epoch micro time>,"version":<php version>}
Deeper Description:
Observed Behavior
Starting at about PHP 8.1.2, The amount of time it takes the php-cgi.exe to spin up once called by IIS' w3wp process has doubled to tripled based on tests I have done. With bare-bones PHP code and Out-Of-Box ini configs, the load times for my local tests have gone from ~.05 seconds for pre PHP 8.1.2 to ~.10-.15 seconds. It's almost unnoticeable but it does leave a possibility of IIS having a higher chance to enter a race condition where it spend too much time spinning up the FastCGI instances versus handling the incoming requests during a sudden influx of traffic.
Testing Conditions
I threw the above PHP script on an IIS server and measured when PHP was able to microtime itself with older versions versus 8.1.2+ versions. My powershell script would timestamp itself, call the page with no FastCGIs running, and then calculate the difference. It was easier to see this performance difference when I ran these requests in parrallel in order to spin up more than just 1 FastCGI at a time. I was also able to get some performance back by disabling opcache, so not sure if that hints at any possible clues.
Restart-WebAppPool "<YourAppPoolHere>"
sleep 5
workflow FastCGIParallel {
param(
[string]$url,
[int]$parallelCount = 10
)
foreach -parallel ($x in 1..$parallelCount) {
#MicroTimestamp Powershell.
$local_time =((Get-Date).ToFileTime() / 10000000 - 11644473600)
#Call the php script.
$response = Invoke-RestMethod -Method Get $url
#Calculate the two timestamps.
$diff = $response.loaded - $local_time
#Output version of PHP (For Sanity Checking).
$version = $response.version
#Echos data to console.
"Load_Time : $diff |Version : $version"
}
}
FastCGIParallel "<YourIISURLHere>" -parallelCount 10
Visual Studio CPU Performance Analysis for "Hello World" Script
Disclaimer
This is my first bug report to PHP so please feel free to critique my submission and suggest corrective actions. I spent a good amount of time trying to make sure this wasn't something I was messing up on my end, but I do believe that there is still room for me to make a mistake here if I am overlooking something.
PHP Version
PHP 8.1.2+, 8.2.0+
Operating System
Windows IIS - Server and Desktop
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reviewing linked pull request #12784, then reproduce the PHP 8.1.2+ FastCGI spin-up timings on Windows IIS with the provided PHP script and PowerShell parallel workflow. Compare older PHP versions and opcache-enabled versus disabled runs; done means identifying and resolving the regression while preserving comparable startup performance.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- php, powershell
- Domain
- backend, operating-systems, performance
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100