Skip to content

Windows IIS FastCGI Spin-Up Performance SlowdownΒ #12778

Open
@djvierus

Description

@djvierus

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

image

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions