WordPress shows “Maximum upload file size: 2 MB” (or 8 MB, or 64 MB) on the Media → Add New screen. That number isn’t a WordPress setting — it comes from PHP, and on your own server there’s also a web server limit to raise. Here’s how to change all of them properly on a VPS.
The limits involved
| Layer | Setting | Typical default |
|---|---|---|
| PHP | upload_max_filesize |
2M |
| PHP | post_max_size (must be ≥ upload size) |
8M |
| PHP | memory_limit (for image processing) |
128M |
| PHP | max_execution_time, max_input_time |
30s / 60s |
| Nginx | client_max_body_size |
1M |
| Apache | LimitRequestBody |
unlimited (since 2.4.54: 1 GB) |
| Multisite | “Max upload file size” network setting | 1.5 MB |
| Cloudflare (if proxied) | Request body limit | 100 MB on Free/Pro |
The smallest limit wins.
1. Find the right php.ini
PHP-FPM, the CLI and Apache’s mod_php each have their own php.ini. Find the one your site uses:
php --ini # CLI — not what the website uses
ls /etc/php/*/fpm/php.ini # PHP-FPM (Nginx, or Apache with FPM)
Or create a temporary info.php with <?php phpinfo(); in the site root, open it, check Loaded Configuration File and the current values — then delete the file.
2. Raise the PHP limits
Rather than editing the main php.ini, add an override file that survives package upgrades. For PHP-FPM 8.3 on Ubuntu/Debian:
sudo tee /etc/php/8.3/fpm/conf.d/99-uploads.ini > /dev/null <<'EOF'
upload_max_filesize = 128M
post_max_size = 128M
memory_limit = 256M
max_execution_time = 300
max_input_time = 300
EOF
sudo systemctl restart php8.3-fpm
post_max_size must be at least as large as upload_max_filesize, because the file travels inside a POST request (along with other form fields).
3. Raise the Nginx limit
Without this, large uploads fail with 413 Request Entity Too Large. In the site’s server block (or http {} in nginx.conf for all sites):
client_max_body_size 128M;
sudo nginx -t && sudo systemctl reload nginx
If Nginx proxies to another backend, also consider proxy_read_timeout for slow uploads. More in Nginx 413 Request Entity Too Large.
3b. Apache
With Apache and mod_php, you can set the PHP values in the virtual host or .htaccess:
php_value upload_max_filesize 128M
php_value post_max_size 128M
These directives only work with mod_php. With PHP-FPM, use the conf.d file from step 2 (or a .user.ini file in the site root). If LimitRequestBody is set anywhere, raise it too:
LimitRequestBody 134217728
4. Verify
Reload Media → Add New — the “Maximum upload file size” line should show the new value. Or check from the shell:
sudo -u www-data php -r 'echo ini_get("upload_max_filesize"), " ", ini_get("post_max_size"), PHP_EOL;'
(That checks the CLI configuration; the media screen shows what PHP-FPM actually uses.)
5. Multisite
Network Admin → Settings → Max upload file size (in KB) caps uploads for all sites in the network, independently of PHP. Raise it as well.
Methods that don’t work on a VPS (or are fragile)
Many tutorials suggest:
- Adding
@ini_set('upload_max_size', '128M');towp-config.phporfunctions.php—upload_max_filesizecan’t be changed at runtime, so this has no effect. php_valuelines in.htaccesson Nginx — Nginx doesn’t read.htaccessat all.- Plugins that “increase upload size” — they can only display limits or work within what PHP allows.
On your own server, change PHP and the web server directly — it’s cleaner and predictable.
How big should the limit be?
Large limits allow larger requests to tie up PHP workers and memory. Pick what you need:
- Typical blog with images: 32–64 MB.
- Podcasts, PDFs, small videos: 128–256 MB.
- Large video files: don’t upload through WordPress. Upload via SFTP to
wp-content/uploadsand register them withwp media import, or use a video platform or object storage.
Importing large files via WP-CLI
sudo -u www-data wp media import /home/deploy/big-video.mp4 --title="Launch video"
WP-CLI runs without the web server’s request limits.
Troubleshooting
- “The uploaded file exceeds the upload_max_filesize directive in php.ini” — PHP limit; the change didn’t reach the FPM config, or PHP-FPM wasn’t restarted.
- 413 Request Entity Too Large — Nginx limit.
- “HTTP error” during image upload — often memory exhaustion while generating thumbnails for large images; raise
memory_limit, or check the PHP error log. - Upload stalls at 100% then fails — timeouts; raise
max_execution_timeand, behind a proxy, the proxy timeouts. - Fails only via Cloudflare — Cloudflare’s request size limit; upload through a non-proxied hostname or increase your plan’s limit.
Related: WordPress memory limit and php.ini settings. On a WordPress VPS you control every one of these limits yourself.