Managing Uploads, Timeouts and PHP Limits in Nginx and Apache


To totally unlock this section you need to Log-in


Login

There are software likes Apache, Nginx, PHP, and phpMyAdmin have multiple configuration settings that define and set limits to:

  • Memory Usage (Allocation)
  • PHP Script Run Times
  • Upload File Sizes

But before to begin exploring some common limit values of these two web servers, we need to locate, on our Linux distribution, where are the configuration files needed to manage the following options and directives.

On most systems if you installed Apache with a package manager, or it came preinstalled, the Apache configuration file is located in one of these locations:

/etc/apache2/httpd.conf
/etc/apache2/apache2.conf
/etc/httpd/httpd.conf
/etc/httpd/conf/httpd.conf

If you installed Apache from source it is likely located in /usr/local or /opt, though the config files may have been moved to /etc as usual. Check your build script for more details.

Instead, all NGINX configuration files are located in the /etc/nginx/ directory. The primary configuration file is /etc/nginx/nginx.conf.

This article could be a good quick guide that will work for both Apache on Linux , Nginx and for all WAMP-servers solutions, like XAMPP (Apache on Windows).

Increasing File Upload Limits

For uploading large files there are Apache and PHP memory limits and timeout values set that you might need to update.

PHP

Regarding XAMPP (but the following directives will be the same even on Linux platforms), open and edit file php.ini, usually available on C:\xampp\Config\Php\php.ini:

These following two settings define the maximum file upload size in yout PHP applications:

upload_max_filesize = 256M
post_max_size = 257M

This will increase upload limits on a single file to 256 MB, from the default of 2 MB. In general post_max_size value must be the same or greater than the upload_max_filesize value to works properly. In this case post_max_size is set 1 MB larger than upload_max_filesize to take into account for any additional meta-data about the file that is included in the request (for example added header data).

If in a single POST request (uploading data) there are multiple files uploads, then post_max_size will need to be set greater than the size of all the files combined, so in this example: post_max_size > upload_max_filesize * number-of-files + 1MB * number-of-files.

Related PHP Settings

file_uploads = On

file_uploads” has to be set as on. And usually is by default under most WAMP and LAMP setups. This setting actually enable file uploads using your PHP application (so you will be able to allow your application to accept file uploads requests).

memory_limit = 258M

While the PHP docs state that memory_limit should generally be set higher than the post_max_size value, is not strictly required to be so, because file uploads are not usually stored/output in their entirety to memory. Instead, they are buffered part-by-part and written out to a file in the temporary directory as the upload progresses.

This setting does not usually affect or limit uploads (nor downloads).

UPLOAD_TMP_DIR

upload_tmp_dir = ""

This is the directory (the default tmp directory is /tmp) where file uploads are temporarily placed. It has to exist, and has to not have special/restrictive permissions set on it. Obviously this folder should have enough free disk space on this partition/disk, and no restrictive space quotas set on this directory.

If you are using your own coded scripts to do file uploads, note that the file will be deleted from the temporary directory automatically by PHP at the end of the request. Before the script exits, you must move or copy away the file.

MAX_INPUT_TIME AND MAX_EXECUTION_TIME

max_input_time = 300

This value represents the amount of time a PHP script can spend parsing and evaluating input data. The default is 60 seconds. This parsing time does not count or include the time represented by the max_execution_time limit value.

max_execution_time = 300

max_execution_time has no effect on upload time limits (i.e., you don’t need to modify “max_execution_time” for file uploads).

Important – these settings are limits on the possible “processing” time of the data, and not on the actual upload time itself (i.e., client upload time does not count towards max_input_time and max_execution_time).

MAX_FILE_UPLOADS

max_file_uploads = 20

The max_file_uploads value represents the maximum number of files (default is 20) that can be uploaded by a single POST request (via a typical form submit). If you are uploading more than 1 file at a time, you’ll also keep in mid that probably you will have to set post_max_size to a greater value than upload_max_filesize times max_file_uploads to be sure that multiple downloads will go smoothly.

PHP-FCGI (PHP-FPM)

FastCGI (FCGI) has been developed as a middle layer between the PHP Apache Module (mod_php) and the CGI application. It allows scripts to be executed by an interpreter outside of the web server (Apache or Nginx) and includes the security benefits of CGI but doesn’t include any of the inefficiencies of CGI.

When executing PHP scripts from a web portal with FastCGI, all requests are passed from the web server to FastCGI via a communication socket (usually local on the same machine). This allows greater scalability (if needed) as the web server and the PHP interpreter could be split into their own individual server environments if necessary.

When using PHP-FCGI (mod_fcgid), it caps uploads to 128KB by default in newer versions (v2.3.6 and above), and usually it will returns a 500 Server Error when that limit is reached.

To modify this behavior we need to edit PHP FCGI file (for apache2 usually in /etc/apache2/conf-available/php7-fpm.conf and for nginx under /etc/php/7.2/fpm/php.ini if PHP 7 is installed):

For Apache, inside the <ifmodule fcgid_module> block, we'll have to add in or edit setting:

FcgidMaxRequestLen 268435456

This will set the max upload value to 256 MB. Or for a 1GB (1024MB) upload limit, use value: 1073741824.

You should probably set this to match whatever max_upload_value you have in php.ini, but this is not necessary.

Also for uploading and downloading files, this timeout needs to reflect the time it takes to upload/download the file:

FcgidBusyTimeout 300

Apache sets by default LimitRequestBody to 0 (specifying an unlimited size limit on the request).

This value can be overridden in any .htaccess file to another value.

Increasing Execution Timeout Limits

For processing requests there are Apache and PHP timeout values set that you might need to update (the default timeout is usually set to 300 seconds / 5 minutes).

Apache Wait Time for Input/Output

Edit the file httpd.conf, usually in /etc/httpd/httpd.conf and set the following parameter:

Timeout 300

This parameter is used by Apache/httpd to define the amount of time that Apache/httpd daemon will wait for input/output, in general. Read more on this parameter on http://httpd.apache.org/docs/2.2/mod/core.html#timeout.

PHP Script Processing & Runtime Limits

Edit the php.ini file, that you can locate by using php -i command and reviewing the Loaded configuration line:

max_execution_time = 300

More info on this parameter are available here: http://php.net/manual/en/info.configuration.php#ini.max-execution-time

PHP FastCGI Processing Timeout

When running PHP-FCGI, the FastCGI configuration sets a value on the time a FastCGI application has to respond to the I/O request (by default this time is 40 seconds).

Edit the file linked to PHP Fcgi configuration, usually in these locations:

For CentOS/RHEL-based distributions:

/etc/httpd/conf.d/fcgid.conf

For Debian/Ubuntu-based distributions:

/etc/apache2/mods-enabled/fcgid.conf

And, finally, increase, if needed, the following timeout values:

FcgidIOTimeout 600
FcgidIdleTimeout 600
FcgidProcessLifeTime 600
FcgidConnectTimeout 600

Also for busy scripts, this timeout needs to reflect the time it takes those scripts to finish:

FcgidBusyTimeout 300

After these changes to the configuration file, just restart the Apache/httpd daemon (service).

In Nginx, you would add these statements in location block like in the following example:

Now let’s add fastcgi_read_timeout variable inside our Nginx virtual host configuration:

location ~ .php$ {
root /var/www/sites/nginxtips.com;
try_files $uri =404;
fastcgi_pass unix:/tmp/php5-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
fastcgi_read_timeout 300;
}

Or even in http block to apply this items to all websites hosted on Nginx on the server, modifying the /etc/nginx/nginx.conf configuration file.

Increasing PHP Memory Limits

Available memory, in PHP, is an important factor to analyse related to how many and how complex will be the PHP scripts we are going to use (if well programmed) on our web portal.

We need to know that PHP memory_limit value, specifically, is per-script configuration (it is like the speed limit for vehicles).

In PHP configuration, PHP’s memory limit for scripts could be set high to 1GB, but this does not mean that scripts will pile up to use that 1GB.

PHP has a limit set on the amount of memory a PHP script is allowed to allocate:

memory_limit = 256M

Usually it is not so wise you don’t want to set a value above 2000 MB (a bit lower than 2GB / 2048MB) because in this way you could exhaust the memory space PHP can use running as a 32 bit process and this could trigger PHP bugs.

Though normally it shouldn’t need to be higher than 1024MB as anything above is usually indicative of bad memory management or memory leakage by the PHP script used.

.htaccess and PHP code that overrides php.ini settings. If you are experiencing an Apache or PHP error message:

Out of memory (allocated X) (tried to allocate Y bytes)

Fox Xampp, for example, by using a text editor, like Notepad++ or similar, search for C:\xampp\php\php.ini and then modify the following text/string (usually only in php.ini) to increase memory limit:

memory_limit

In addition, check if in any memory_limit statement has been set in any .htaccess files (via directive: php_value memory_limit) or in PHP files of your web portal (via function: ini_set()). If found, then manually edit or comment out those lines.

In an .htaccess file you could override php.ini’s memory_limit value by using the following statement:

php_value memory_limit 20M

But also in a PHP script you could override php.ini’s memory_limit:

ini_set("memory_limit","20M");

In these web server you could also, in the website’s VirtualHost file a value that is not overridable via .htaccess files nor script PHP code by using the php_admin_value directive, as in the following example:

php_admin_value memory_limit 256M

In Nginx, you could set this statement directly in PHP-FPM configuration file (/etc/php5/fpm/php-fpm.conf for PHP 5.x for example).

So, the main difference between memory_limit = 256M in php.ini and php_admin_value[memory_limit] = 32M in pool.d/www.conf (PHP-FPM in PHP 7.x) is that you can use ini_set('memory_limit','512M') to override the setting in php.ini but you can't override values set with php_admin_value.

Increasing phpMyAdmin Limits

phpMyAdmin has a default limit of 300 seconds set on the import and export of dump (SQL) files. This setting does not affect the run time of any other phpMyAdmin functions.

Edit file \phpMyAdmin\config.inc.php:

$cfg['ExecTimeLimit'] = 300;

phpMyAdmin also has a $cfg[‘MemoryLimit’] setting that limits the amount of memory a script can allocate for importing and exporting SQL files (this is useful to limit the chance to block phpMyAdmin portal during SQL data import), but its default value is already set with no limit:

$cfg['MemoryLimit'] = '0';

To set this value with a specific value, instead of letting PHP handle this limit, you will have to append an M to the value.

Note about Nginx and PHP

Depending on your Linux distribution and PHP version, the PHP configuration files will be stored in different locations. For example, if you are using PHP 7.0 from Ubuntu’s repositories, you can find the proper PHP files locations (full paths) to modify by using the following command (find):

find / \( -iname "php.ini" -o -name "www.conf" \)

The output should look similar to:

/etc/php/7.0/fpm/php.ini
/etc/php/7.0/fpm/pool.d/www.conf
/etc/php/7.0/cli/php.ini