# PHP Without Timeout¶

Some PHP scripts need to run for long periods of time without interruption. Examples include WordPress modules such as BackupBuddy, ImportBuddy, or any other module that relies on a WordPress built-in cron job. Whenever a PHP application rebuilds MySQL indexes, the process may run for a long time.

Generally, allowing a PHP script to run forever is not desirable. Thus there are a number of features (in LiteSpeed Web Server and built into PHP itself) that may prevent a PHP process from running long enough to finish. You may need to set up more than one of the following configurations to ensure your application works correctly.

## Easiest Solution¶

The easiest way to avoid aborting long-running PHP scripts is to place the following code into the very top of the domain's document root .htaccess:

<IfModule Litespeed>
RewriteEngine On
RewriteRule .* - [E=noabort:1, E=noconntimeout:1]
</IfModule>

To learn more, read through the rest of this documentation. It explains in detail what noabort and noconntimeout do for long-running PHP scripts and how to implement them through different methods, if you wish.

## Turn off Broken Connection Aborting¶

When a user closes a connection (by closing a window, for example), LSWS will abort processing that PHP script by killing the PHP process. This is to avoid wasting system resources and to prevent certain types of DoS attacks.

In some cases, though, it is preferable not to abort the PHP script, regardless of whether the connection has been closed. For example, built-in WordPress cron jobs start a background job by sending a request to wp-cron.php, then immediately closing the connection without waiting for a response. In order for the cron job to complete, though, the web server must keep the PHP engine running without interruption.

In this case, you need to turn off broken connection aborting. This be done at the server level in LSWS's WebAdmin Console or by using LiteSpeed's noabort environment variable.

Tip

With Apache mod_php, the ignore_user_abort setting allows a user to trigger a long-running process and then close the browser or navigate away from the page without killing the PHP/MySQL process. This setting (and any Apache suEXEC setup) is not supported by LSWS.

Navigate to WebAdmin console > Configuration > Server > General and set External Application Abort to No Abort. This will stop all applications from aborting even when a connection has been broken.

Warning

It is not recommended to to turn off the abort at the server level, except in rare, nontradtional use cases.

### By Request Via Environment Variable¶

Aborting for a broken connection can be turned off by using the request-level noabort environment variable. This can be done in a rewrite rule or by using the SetEnv/SetEnvIf directives. noabort is a LiteSpeed-specific environment variable, so all of the following rules should be placed in

<IfModule Litespeed>
...
</IfModule>


The [E=noabort:1] flag can be added to any rewrite rule. The rewrite rule can be in an Apache .htaccess file or vhost-level configuration file. The rewrite flag should generally be used for a single account only.

If you need to do a server-level configuration that will apply to all accounts (though perhaps only for certain scripts), you should use the SetEnvIf directive.

Note

Rewrite rules and SetEnv should not be used together. We recommend choosing the SetEnv directive over rewrite rules for two reasons:

1. Rewrite rules are sensitive to position among the other rules. SetEnv can go anywhere in the config file.
2. Rewrite rules cannot be easily inherited. To impact all accounts with one setting, the SetEnvIf directive should be used.

Directive example for all requests

SetEnv noabort 1


Directive example for wp-cron.php, backupbuddy.php, and importbuddy.php only

SetEnvIf Request_URI "(wp-cron|backupbuddy|importbuddy)\.php" noabort


Rewrite rule example for all requests

RewriteEngine On
RewriteRule .* - [E=noabort:1]


Rewrite rule example for wp-cron.php, backupbuddy.php, and importbuddy.php only

RewriteEngine On
RewriteRule (wp-cron|backupbuddy|importbuddy)\.php - [E=noabort:1]


## Override LiteSpeed Connection Timeout¶

If a script does not send back anything for a long time, this can trigger a connection timeout, and the server will close the client connection. This is done to prevent poorly written PHP scripts from tying up the server. To get desired functionality from your web applications, though, you may need to prevent the connection from being timed out. (If the noabort environment variable above has been set, the script will continue to run even though the connection has been broken. Your application, though, may require the connection to stay open for correct functionality.)

Connection timeout can be prevented by either increasing the global connection timeout setting (via the WebAdmin console) or using LiteSpeed's noconntimeout environment variable.

Navigate to WebAdmin CP > Configuration > Server > Tuning and change Connection Timeout. This setting can be increased to allow scripts to run for more seconds (though they will still time out after the newly specified time has elapsed).

Tip

### By Request Via Environment Variable¶

Similar to the noabort environment variable, you can add the noconntimeout environment variable via a rewrite rule or using the SetEnv/SetEnvIf directives. (The rewrite flag is preferred for controlling a single account. The SetEnv/SetEnvIf directives are preferred for rules that will apply to all accounts.) noconntimeout is a LiteSpeed-specific environment variable, so all of the following examples should be placed inside:

<IfModule Litespeed>
...
</IfModule>


Directive example for wp-cron.php, backupbuddy.php, and importbuddy.php only combined with noabort

SetEnvIf Request_URI "(wp-cron|backupbuddy|importbuddy)\.php" noabort noconntimeout


Rewrite rule example for all requests

RewriteEngine On
RewriteRule .* - [E=noconntimeout:1]


Rewrite rule example for wp-cron.php, backupbuddy.php, and importbuddy.php only

RewriteRule (wp-cron|backupbuddy|importbuddy)\.php - [E=noconntimeout:1]


Rewrite rule example combined with noabort

RewriteRule (wp-cron|backupbuddy|importbuddy)\.php - [E=noabort:1, E=noconntimeout:1]


## Set LSAPI_MAX_PROCESS_TIME Environment Variable¶

In ProcessGroup mode, the LSAPI_MAX_PROCESS_TIME environment variable controls the maximum processing time allowed when processing a request (default 3600 seconds). If a child process cannot finish processing the request in the given time period, it will be killed by the parent process. This option can get rid of a dead or a runaway child process.

Set the environment variable in your external application settings at WebAdmin > Configuration > Server(or Vhost) > External App > your external application > Environments.

## Set PHP Execution Time in php.ini¶

The max_execution_time setting controls the maximum time in seconds a PHP script is allowed to run before it is terminated by the parser. This helps prevent poorly written scripts from tying up the server. This time does not include time spent in system calls or network I/O (unlike the LSAPI_MAX_PROCESS_TIME environment variable above). Thus a process will usually trigger LSAPI_MAX_PROCESS_TIME before triggering a max_execution_time setting of a similar length. The default setting is 30.

Example setting (in a php.ini file):

    max_execution_time=36000


## Add PHP Code to a Script¶

One of our customers had success making sure a PHP script did not time out by adding the following PHP code:

<?php
//avoid apache to kill the php running
ignore_user_abort(true);
//start buffer output
ob_start();

echo "show something to user";
//close session file on server side to avoid blocking other requests
session_write_close();

//really send content, can't change the order:
//1.ob buffer to normal buffer,
//2.normal buffer to output
ob_end_flush();
flush();
//continue do something on server side
ob_start();
//replace it with the background task
sleep(50);
ob_end_clean();
?>


Note

You need to turn off keepalive connections for this request. This can be done with a rewrite rule.

## Troubleshooting¶

### noabort Rule is Ignored¶

In this example, a test.php script sets sleep time to 320 seconds, like so:

?php

//Store the micro time so that we know
//when our script started to run.
$executionStartTime = microtime(true); // displaying time echo date('h:i:s')."\n" ; // delaying execution of the script for 2 seconds sleep(320); // displaying time again echo date('h:i:s'); //At the end of your code, compare the current //microtime to the microtime that we stored //at the beginning of the script.$executionEndTime = microtime(true);

//The result will be in seconds and milliseconds.
$seconds =$executionEndTime - $executionStartTime; //Print it out echo "This script took$seconds to execute.";
?>


When it is run, however, it errors out and stops at 300 seconds (5 minutes). phpinfo.php shows max_execution_time is 600. The script times out due to LiteSpeed Web Server's default 300-second timeout. The default, however, can be overridden by a noabort or noconntimeout rule.

In this example, .htaccess does have a noabort rule, but the test script still stops at 300 seconds:

Oct8ne
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteRule ^oct8ne/frame/([a-zA-Z]+)$index.php?fc=module&module=oct8ne&controller=oct8neconnector&octmethod=$1&%{QUERY_STRING} [QSA,L]
</IfModule>
#End_Oct8ne
# ~~start~~ Do not remove this comment, Prestashop will keep automatically the code outside this comment when .htaccess will be generated again
# .htaccess automaticaly generated by PrestaShop e-commerce open-source solution
# http://www.prestashop.com - http://www.prestashop.com/forums

<IfModule mod_rewrite.c>
<IfModule mod_env.c>
SetEnv HTTP_MOD_REWRITE On
</IfModule>

RewriteEngine on

#
RewriteRule . - [E=REWRITEBASE:/]
RewriteRule ^api$api/ [L] RewriteRule ^api/(.*)$ %{ENV:REWRITEBASE}webservice/dispatcher.php?url=$1 [QSA,L] # Images RewriteRule ^([0-9])(\-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+\.jpg$ %{ENV:REWRITEBASE}img/p/$1/$1$2$3.jpg [L]
RewriteRule ^([0-9])([0-9])(\-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+\.jpg$%{ENV:REWRITEBASE}img/p/$1/$2/$1$2$3$4.jpg [L] RewriteRule ^([0-9])([0-9])([0-9])(\-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+\.jpg$ %{ENV:REWRITEBASE}img/p/$1/$2/$3/$1$2$3$4$5.jpg [L]
RewriteRule ^([0-9])([0-9])([0-9])([0-9])(\-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+\.jpg$%{ENV:REWRITEBASE}img/p/$1/$2/$3/$4/$1$2$3$4$5$6.jpg [L] RewriteRule ^([0-9])([0-9])([0-9])([0-9])([0-9])(\-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+\.jpg$ %{ENV:REWRITEBASE}img/p/$1/$2/$3/$4/$5/$1$2$3$4$5$6$7.jpg [L]
RewriteRule ^([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])(\-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+\.jpg$%{ENV:REWRITEBASE}img/p/$1/$2/$3/$4/$5/$6/$1$2$3$4$5$6$7$8.jpg [L] RewriteRule ^([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])(\-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+\.jpg$ %{ENV:REWRITEBASE}img/p/$1/$2/$3/$4/$5/$6/$7/$1$2$3$4$5$6$7$8$9.jpg [L]
RewriteRule ^([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])(\-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+\.jpg$%{ENV:REWRITEBASE}img/p/$1/$2/$3/$4/$5/$6/$7/$8/$1$2$3$4$5$6$7$8$9$10.jpg [L] RewriteRule ^c/([0-9]+)(\-[\.*_a-zA-Z0-9-]*)(-[0-9]+)?/.+\.jpg$ %{ENV:REWRITEBASE}img/c/$1$2$3.jpg [L] RewriteRule ^c/([a-zA-Z_-]+)(-[0-9]+)?/.+\.jpg$ %{ENV:REWRITEBASE}img/c/$1$2.jpg [L]
# AlphaImageLoader for IE and fancybox
RewriteRule ^images_ie/?([^/]+)\.(jpe?g|png|gif)$js/jquery/plugins/fancybox/images/$1.$2 [L] # Dispatcher RewriteCond %{REQUEST_FILENAME} -s [OR] RewriteCond %{REQUEST_FILENAME} -l [OR] RewriteCond %{REQUEST_FILENAME} -d RewriteRule ^.*$ - [NC,L]
RewriteRule ^.*$%{ENV:REWRITEBASE}index.php [NC,L] AddType application/vnd.ms-fontobject .eot AddType font/ttf .ttf AddType font/otf .otf AddType font/woff2 .woff2 AddType application/x-font-woff .woff <IfModule mod_headers.c> <FilesMatch "\.(ttf|ttc|otf|eot|woff|woff2|svg)$">
</FilesMatch>
</IfModule>

#If rewrite mod isn't enabled
ErrorDocument 404 /index.php?controller=404

# ~~end~~ Do not remove this comment, Prestashop will keep automatically the code outside this comment when .htaccess will be generated again

# # BEGIN litespeed noconntimeout noabort
<IfModule Litespeed>
RewriteEngine On
RewriteRule .* - [E=noabort:1]
</IfModule>
# # END litespeed noconntimeout noabort

# php -- BEGIN cPanel-generated handler, do not edit
# Set the “ea-php70” package as the default “PHP” programming language.
<IfModule mime_module>
</IfModule>
# php -- END cPanel-generated handler, do not edit

# BEGIN cPanel-generated php ini directives, do not edit
# Manual editing of this file may result in unexpected behavior.
# To make changes to this file, use the cPanel MultiPHP INI Editor (Home >> Software >> MultiPHP INI Editor)
<IfModule php7_module>
php_flag display_errors Off
php_value max_execution_time 600
php_value max_input_time 600
php_value max_input_vars 6000
php_value memory_limit 1024M
php_value post_max_size 1024M
php_value session.save_path "/var/cpanel/php/sessions/ea-php73"
php_flag zlib.output_compression Off
</IfModule>
<IfModule lsapi_module>
php_flag display_errors Off
php_value max_execution_time 600
php_value max_input_time 600
php_value max_input_vars 6000
php_value memory_limit 1024M
php_value post_max_size 1024M
php_value session.save_path "/var/cpanel/php/sessions/ea-php73"
php_flag zlib.output_compression Off
</IfModule>
# END cPanel-generated php ini directives, do not edit


The problem is the position of the noabort rule. It was placed nearly at the end of .htaccess, and as such, it is prevented from being executed by the other rules that come before it.

RewriteRule .* - [E=noabort:1]


Move the rule to the very top of all .htaccess rewrite rules, and the test script will no longer time out.

Last update: July 12, 2021