Troubleshoot – My PHP script is timing out

Posted: Feb 08, 2010  1 comments  

Average Rating

Tags
FastCGI
IIS
PHP
PHP Script TimeOut

Share this Post

I hear a lot about the problem where web server (IIS) throws an error saying that PHP script has timed out in our forums. Let’s try to understand the reason behind this. I will be using a Windows 7 Enterprise machine (having IIS 7.5) to explain this but this should be applicable to Windows 2008/Windows Vista too. The same can be told true for Windows 2003/Windows XP with some difference like IIS stores FastCGI configuration in fcgiext.ini file rather than application meta-base. However the concept should be exactly similar.

Let me now summarize some of the IIS FastCGI settings and PHP INI configuration directive to ensure that everyone is on the same page and which are most important for this discussion.

Two important FastCGI settings:

  • ActivityTimeout – This is the number of seconds that the FastCGI handler waits for I/O activity from a process before it is terminated. At some place you will also find this as being documented as number of seconds PHP-CGI process can run without communicating to IIS.
  • RequestTimeout – This is the maximum amount of time in seconds that a FastCGI process is allowed to handle a request before it is terminated.
  • Important PHP INI directive for this discussion:

  • max_execution_time – This is the maximum time in seconds a script is allowed to run before it is terminated by parser. Details can be seen at http://www.php.net/manual/en/info.configuration.php#ini.max-execution-time.
  • All the above three impacts your script execution time. Ideally you will have the value of RequestTimeout greater than or equal to ActivityTimeout. Well this is not a hard rule but going by meaning of these two timeouts it makes sense to do this. Assume you are uploading a file of size ‘X’ MB and it takes 500 second to upload it (assuming PHP is configured properly to allow upload of files and so the size of ‘X’ MB is also allowed) and you have below value for the two timeouts:

    ActivityTimeout=501

    RequestTimeout=400

    This configuration will result into request timeout while uploading the file. The reason is that though an I/O operation (in this case file upload) is allowed for 501 seconds which is perfectly fine for this case, request time out is less than 501 (and is at 400) and so FastCGI will encounter a request timeout. Remember this will be done by the web server (IIS here) and not PHP. So setting the value of RequestTimeout higher than ActivityTimeout makes more sense.

    However assume your max_execution_time is set to 300 seconds and you are running a PHP script which executes for time more than 300 seconds and FastCGI timeout settings are same as above. This time PHP will terminate itself.

    This implies that (assuming you have RequestTimeout set to a value higher than ActivityTimeout) you script will run maximum for time in seconds which is configured for max_execution_time or RequestTimeout whichever is less.

    This should help you configuring the PHP script to run for a longer period of time.

    Some Frequently asked question

    • I am changing the fastcgi.ini file or php.ini file but settings are not getting effected on XP/2k3 or I am changing applicationhost.config or php.ini on a IIS7 machine and changes are not getting effected.

    Please recycle the application pool or restart the server to make the FastCGI/PHP process read the new settings. If you are using latest FastCGI and you do not want to restart the application and want changes to be picked up on it’s own you can as well use the feature called ‘Monitor Changes to File’. Details about this can be found at http://blogs.iis.net/ksingla/archive/2009/01/22/improvements-to-fastcgi-in-iis-7-5.aspx for IIS7.5 and at http://learn.iis.net/page.aspx/248/configure-the-fastcgi-extension-for-iis-60/ for IIS6.0. For information regarding if this feature is supported on your configuration or not please refer to blog post at http://blogs.iis.net/ruslany/archive/2010/02/05/fastcgi-module-differences-across-iis-versions.aspx. We are working to make the features available across all configuration however.

    • But I would like to set the FastCGI settings different for different sites. How do I do that for IIS6.0?

    The answer to this is well explained in the comment section of fcgiext.ini file. I am pasting it below for easy reference.

    ; The main section of the fcgiext.ini file is the [types] section.  This
    ; section associates file extensions from the URL with FastCGI applications.
    ;
    ; The general syntax is a follows:
    ;
    ; [types]
    ; abc=Application 1
    ; def:/lm/w3svc/1701187997/root/app1=Application 2
    ; *:/lm/w3svc/1701187997/root/app1=Application 3
    ; def:1701187997=Application 4
    ; *:1701187997=Application 5
    ; def=Application 6
    ; *=Application 7
    ;
    ; The above example consists of 7 mappings mapped as follows:
    ;
    ; - The file extension "abc" is associated with the FastCGI application
    ;   named "Application 1".
    ;
    ; - The file extension "def" is associated with the FastCGI application
    ;   named "Application 2", but only for requests made to the application
    ;   /app1 under site with the numeric identifier "1701187997".  Note that
    ;   application specific mappings override site, extension specific mappings.
    ;
    ; - Requests to the application /app1 under web site with the identifier
    ;   "1701187997" with a file extension other than "def" are associated
    ;   with the FastCGI application named "Application 3".
    ;
    ; - The file extension "def" is associated with the FastCGI application
    ;   named "Application 4", but only for requests made to the applications
    ;   other than /app1 under web site with the numeric identifier
    ;   "1701187997". Note that site specific mappings override non-site
    ;   specific mappings.
    ;
    ; - Requests to the applications other than /app1 under web site with the
    ;   identifier "1701187997" with a file extensions other than "def" are
    ;   associated with the FastCGI application named "Application 5".
    ;
    ; - The file extension "def" is associated with the FastCGI application
    ;   named "Application 6" for requests which are not for site with numeric
    ;   identifier "1701187997".
    ;
    ; - Requests with a file extension that does not have a specific mapping
    ;   are associated with the FastCGI application named "Application 7".
    ;
    ; Note that application names are ASCII and should generally contain only
    ; alphanumeric characters, and spaces are allowed.  Application names are
    ; case-insensitive.
    ;
    ; Note also that it is allowed for multiple mappings to be associated with
    ; the same FastCGI application.
    ;
    ; The following is a sample application section.  Note that the name of
    ; the section must correspond to at least one mapping in the [types] section
    ; in order to be used:

    Example:

    [Types]
    php:185983572=Site1
    php:237389121=Site2
    php=AllOther

    [Site1]
    ExePath=C:\php\php-cgi.exe
    ActivityTimeout=90
    RequestTimeout=120

    [Site2]
    ExePath=C:\php\php-cgi.exe
    ActivityTimeout=60
    RequestTimeout=90

    [AllOther]
    ExePath=C:\php\php-cgi.exe
    ActivityTimeout=70
    RequestTimeout=100

    This will ensure different values of activity and request timeouts for Site1 and Site2 which can be differentiated by site’s numeric id 185983572 and 237389121 respectively. For all other sites, the configuration setting under [AllOther] section will be applied.

    • Okay, how to achieve the above thing on IIS7?

    Please use the link at http://learn.iis.net/page.aspx/246/using-fastcgi-to-host-php-applications-on-iis-70/#Per-site_PHP_configuration to get the details.

    • How about having different PHP INI setting (here max_execution_time) for different sites?

    If you are on IIS6 specify Arguments=-d max_execution_time=600 for Site1 in the above example and Arguments=-d max_execution_time=600 for Site2 in the above example and PHP-CGI.EXE will be passed different values for rule matching Site1 and Site2 respectively. For all other sites default value of max_execution_time or one defined in PHP.INI file will be used. If you are using PHP5.3 and above, you can also use PHP_INI_PERDIR for doing this isolation. The blog at http://blogs.iis.net/donraman/archive/2009/11/08/enabling-wincache-on-per-site-basis.aspx explains it for how to do it for WINCACHE directives but can be used as a guide to set any PHP INI directives so far as that directive supports PHP_INI_PERDIR configuration.

    • Is there a limit on maximum values for the above settings? If yes, how can I find the maximum values? And how do I change it?

    Yes, there is a limit to maximum value. For IIS7 it is present in the IIS schema file. The schema file can be found at %WINDIR%\system32\inetsrv\config\schema and the file is named IIS_schema.xml. Look at section named "system.webServer/fastCgi" for defaults. It seems the maximum value for these two FastCGI settings is 70 days on Windows 7. And yes if you are administrator on IIS7 box, you can change the default values but I would advise not to do that. For IIS6 look at the file named MBSchema.xml inside folder %SystemRoot%\System32\Inetsrv.

    Hopefully all this information will help you from getting around timeout problem for PHP scripts. Thanks for the patient reading and till the time we meet again ‘Good Bye’.

    Thanks,

    Don.