GICT knowledge base
How to Increase PHP Upload Max Filesize on Apache and Nginx
Published
Anyone who has built a PHP application that handles file uploads has hit this wall. A user tries to upload a video, a Portable Document Format (PDF) file, or a high-resolution image, and the upload silently fails. The form looks like it submitted, but nothing happens. You check the logs and find nothing useful. The problem is almost always the same. PHP has a default upload size limit that is far too small for modern files, and Apache or Nginx might have their own limits stacked on top.
In this article, you will learn why PHP limits upload sizes, which configuration values actually matter, how to change them on Apache and Nginx, how to verify the new limits are working, and which mistakes catch people during the process. By the end, your application will accept the file sizes your users actually need to upload.
Prerequisites
Before you start, make sure you have:
- A Linux machine running Ubuntu 22.04, Debian 12, or a similar distribution.
- A user account with sudo access.
- PHP 8.0 or newer installed and running.
- Either Apache or Nginx serving your PHP application.
- Some way to test uploads, like a working PHP application or a small test script.
Why PHP Limits Upload Sizes
The default upload limit in PHP is 2 MB, which sounds tiny but made sense when the defaults were set years ago. The reason for the limit is not arbitrary. Large uploads consume real resources on the server.
When a user uploads a file, the server has to receive the entire file before it can do anything with it. While that file is in transit, it occupies a connection, uses memory, and writes to disk. A site that allows unlimited uploads is also a site where one user can tie up the server by uploading a 50 GB file over a slow connection.
The default limit also exists as a safety net. Without one, a misconfigured form could accept terabyte-sized uploads and eat all the disk space. Setting a sensible limit forces you to think about what your application actually needs to handle.
So the goal is not to remove the limit. It is to set the limit to a number that fits your real use case. A photo sharing site might need 50 MB. A video platform might need 500 MB or more. A document upload form probably only needs 20 MB.
The PHP Settings That Actually Matter
There are several PHP configuration values involved in file uploads, and they all have to agree with each other. Setting one without the others causes confusing failures.
- upload_max_filesize sets the maximum size of a single uploaded file. This is the headline setting and the one most people think of.
- post_max_size sets the maximum size of the entire POST request, including all files and form fields combined. This needs to be at least as large as
upload_max_filesize, and usually larger. - memory_limit controls how much memory a single PHP script can use. If your application processes the uploaded file in memory, this needs to be larger than the file size.
- max_execution_time sets how long a script can run. Large uploads on slow connections can take a while, and if execution time runs out mid-upload, the request fails.
- max_input_time sets how long PHP will spend parsing input data, including uploads. This is separate from
max_execution_timeand often forgotten.
The relationship between these is the part that trips people up. If upload_max_filesize is 100 MB but post_max_size is 8 MB, uploads larger than 8 MB will fail even though upload_max_filesize says 100 MB is fine. The smaller value always wins.
A common rule of thumb is to set post_max_size slightly larger than upload_max_filesize to leave room for form fields, and to set memory_limit larger than post_max_size to give the script room to work.
Find Your PHP Configuration File
Before changing anything, you need to know which php.ini file is actually being used. PHP can have multiple configuration files for different environments, and editing the wrong one is a common waste of time.
Find the active configuration file.
php --ini
The output shows the loaded configuration file path. On most systems, you will see something like /etc/php/8.2/cli/php.ini for the command-line interface and a separate file for the web server interface.
Find the file used by Apache or PHP-FPM specifically.
php -r "echo php_ini_loaded_file();"
This shows the file PHP itself reports as loaded. For Apache with mod_php, you usually edit the Apache-specific file. For PHP-FPM (which is more common with Nginx), you edit the FPM file.
The paths typically look like:
- Apache with mod_php:
/etc/php/8.2/apache2/php.ini - PHP-FPM (used with Nginx):
/etc/php/8.2/fpm/php.ini - Command line:
/etc/php/8.2/cli/php.ini
[!NOTE] Editing the CLI php.ini file does nothing for web requests. Make sure you edit the file used by the web server’s PHP setup, not the one used by command-line scripts.
Update PHP Settings
Once you know which file to edit, the changes themselves are straightforward.
Open the relevant php.ini file. The example below uses the PHP-FPM configuration for PHP 8.2.
sudo nano /etc/php/8.2/fpm/php.ini
Find and update the upload-related directives. Use the search function in your editor to find each one.
ini
upload_max_filesize = 100M
post_max_size = 110M
memory_limit = 256M
max_execution_time = 300
max_input_time = 300
Adjust the values to fit your application. The example above supports uploads up to 100 MB, with some room for form fields and processing.
Save the file and exit the editor.
Restart the relevant service. For PHP-FPM:
sudo systemctl restart php8.2-fpm
For Apache with mod_php:
sudo systemctl restart apache2
The changes take effect after the restart. PHP does not reload php.ini automatically when you save it, which catches people off guard regularly.
Configure Apache for Larger Uploads
If you are running Apache, the PHP changes above are usually enough. Apache itself does not impose strict upload limits by default, but a few directives can affect how it handles large requests.
Check whether your Apache configuration has a LimitRequestBody directive set.
sudo grep -r "LimitRequestBody" /etc/apache2/
If the command returns no results, Apache has no body size limit and you do not need to do anything. If it shows a value smaller than your desired upload size, you need to update it.
If you need to set or update the directive, edit the relevant configuration file. The right place depends on your setup, but the main config or a virtual host file is common.
sudo nano /etc/apache2/sites-available/example.com.conf
Add or update the LimitRequestBody line inside the VirtualHost block.
apache
ServerName example.com
DocumentRoot /var/www/example
LimitRequestBody 115343360
# other directives
The value is in bytes. The example above sets the limit to 110 MB. Setting it to 0 removes the limit entirely, but that is not recommended.
Test the configuration.
sudo apache2ctl configtest
Reload Apache.
sudo systemctl reload apache2
If you are using .htaccess files, you can also set PHP values there for mod_php setups, though this is less common in modern hosting.
apache
php_value upload_max_filesize 100M
php_value post_max_size 110M
This approach only works with mod_php, not with PHP-FPM, so most modern installs need to use php.ini instead.
Configure Nginx for Larger Uploads
Nginx requires explicit configuration to allow larger uploads, regardless of what PHP says. The default client_max_body_size is 1 MB, which is much smaller than typical PHP defaults.
Edit the Nginx site configuration.
sudo nano /etc/nginx/sites-available/example.com
Add or update the client_max_body_size directive in the server block.
nginx
server {
listen 80;
server_name example.com;
root /var/www/example;
index index.php index.html;
client_max_body_size 110M;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php8.2-fpm.sock;
}
}
The value should be at least as large as post_max_size in PHP, ideally a little larger to avoid edge cases at the boundary.
For long-running uploads, you might also want to increase the FastCGI timeout values to match your PHP configuration.
nginx
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php8.2-fpm.sock;
fastcgi_read_timeout 300;
fastcgi_send_timeout 300;
}
Test the Nginx configuration.
sudo nginx -t
Reload Nginx.
sudo systemctl reload nginx
[!WARNING] If client_max_body_size is smaller than what PHP allows, Nginx returns a 413 error before the request ever reaches PHP. The error message in the browser is generic and does not mention which layer rejected the upload, which makes this surprisingly hard to debug if you do not know about it.
Verify the New Limits
After making changes, you should confirm the new values are actually in effect. Trusting that the changes worked without verifying is how people end up debugging the same problem twice.
Create a small PHP file to display the current settings.
sudo nano /var/www/example/phpinfo.php
Add the following content.
php
<?php
phpinfo();
Visit the file in a browser at http://example.com/phpinfo.php.
Search the page for upload_max_filesize and post_max_size. The displayed values should match what you set.
Delete the file when you are done.
sudo rm /var/www/example/phpinfo.php
Leaving phpinfo() files exposed on a public server is a real security risk. They reveal a lot about your environment, including paths, modules, and version numbers that attackers can use.
For a quicker check from the command line:
php -i | grep -E "upload_max_filesize|post_max_size|memory_limit"
Note that this shows the CLI configuration, which might differ from the web configuration. The PHP info page in a browser is the more reliable check.
Common Problems and How to Fix Them
A few specific issues come up often when adjusting upload limits. Recognizing the symptoms saves time.
- Uploads still fail at the old limit after editing php.ini. The most common cause is editing the wrong configuration file. Use
php --inifrom the same context as your web server to find the right file. Another cause is forgetting to restart PHP-FPM or Apache after the change. - The upload starts but fails partway through. This is usually a timeout issue. Either
max_execution_timeandmax_input_timeare too short, or the FastCGI timeout in Nginx is too low. All three need to allow enough time for the upload to complete on a slow connection. - The browser shows a 413 error. This is Nginx rejecting the request because of
client_max_body_size. PHP never gets the request, so changing PHP settings does nothing. Update the Nginx configuration. - Uploads work in development but fail in production. Usually a configuration mismatch. The development server might have different limits, or might use Apache while production uses Nginx. Verify the limits at every layer in production.
- The upload form just resets without an error. PHP silently rejects uploads larger than
post_max_sizewithout populating the usual$_FILESarray. The application needs to check$_SERVER['CONTENT_LENGTH']against the limit and show a useful error if the upload is too large.
A Note on Architecture
Increasing PHP upload limits is the right answer for many applications, but for very large files there are better approaches.
For files over a few hundred megabytes, consider direct uploads to object storage. Services like Amazon Simple Storage Service (S3), DigitalOcean Spaces, and Google Cloud Storage support presigned URLs that let users upload directly from the browser without the file ever passing through your PHP application. This bypasses PHP and web server limits entirely and scales much better.
For applications that need resumable uploads, libraries like tus-php implement the tus protocol, which handles network failures and large files gracefully. Browsers can pause and resume uploads, which matters a lot when users are uploading on mobile networks.
These approaches are more work upfront but pay off when you start dealing with media files, backups, or any workload involving genuinely large data.
Conclusion
You now know which PHP settings control upload limits, how they relate to each other, how to update them, how to configure Apache and Nginx to allow larger requests, and how to verify the changes are actually working. You also know which problems catch people most often and when to consider a different architecture entirely.
File uploads sound like a simple feature until you actually implement them at scale. The configuration alone touches PHP, the web server, and sometimes the application code. Getting the limits right is just the first step. Past that, you start thinking about validation, virus scanning, storage quotas, and all the other things that make a real upload system robust. But none of that matters if the upload fails at 2 MB, so start with the limits and build from there.
Related guides
How TO: Debugging 500 errors on zencart
Troubleshooting Your Zen Cart: A Quick Guide to Debugging Running an e-commerce site on InterServer’s high-performance hosting gives you a great head start, but even the...
PHPPHP Versions on cPanel: Everything You Need to Know
PHP Versions on cPanel: Everything You Need to Know If you are running a PHP site here at InterServer, you have probably seen notifications in your dashboard talking...
PHPHow to Install or Upgrade to PHP8.4 in Ubuntu
Upgrade to PHP 8.4 on Ubuntu 24.04 for real-world speed boosts, better error handling, and smoother Laravel, WordPress, and Symfony support.
PHPHow to Run Secure Laravel Apps on Ubuntu Using NGINX and PHP 8.3
Learn how to host a secure Laravel applications on Ubuntu with Nginx and PHP8.3. Learn How to secure and optimise your app with this step by step tutorial.
