Most WordPress errors that look mysterious come from a handful of numbers in php.ini. PHP ships with conservative defaults — 128 MB of memory, 2 MB per upload, 1,000 form fields per request — and a modern WordPress site, with a page builder, WooCommerce and a large menu, runs past them sooner than most people expect.
This page lists PHP’s defaults, what breaks when WordPress hits each one, and what to set instead. One of them deserves special attention: max_input_vars, the limit that fails without an error message. We tested it to show exactly what happens.
This page is part of our series of server references, alongside default request size limits, default timeouts, control panel ports and how to verify search engine and AI crawlers.
php.ini-production; WordPress limits from the WordPress 7.1.2 source code. Hosting providers usually change several of these — check your own values before relying on a default.Check your PHP settings
Paste your Site Health info or a phpinfo() page. The checker reads the PHP limits your site runs with, flags the ones that break WordPress and writes the lines to fix them.
In WordPress, go to Tools, Site Health, Info and click Copy site info to clipboard.
Everything runs in your browser: nothing you paste is sent or stored. Checks follow PHP’s documented defaults and the WordPress source code. Source: copahost.com
PHP defaults at a glance
PHP has two sets of defaults: the built-in value, used when no configuration file sets the directive, and the value in php.ini-production, the configuration most servers start from. They’re usually the same — where they differ, both are shown.
| Setting | PHP default | What breaks in WordPress | A common WordPress value |
|---|---|---|---|
memory_limit | 128M | “Allowed memory size of … bytes exhausted” — a white screen or a 500 error | 256M |
max_execution_time | 30 seconds | “Maximum execution time of 30 seconds exceeded” — imports, backups and updates stop halfway | 60–300 |
max_input_time | -1 built in · 60 in production | Slow uploads over weak connections are cut off | 60–300 |
upload_max_filesize | 2M | “The uploaded file exceeds the upload_max_filesize directive” | 64M |
post_max_size | 8M | “The link you followed has expired” when uploading a theme or plugin | Slightly above upload_max_filesize — 72M |
max_file_uploads | 20 | Bulk uploads stop after 20 files | 50 |
max_input_vars | 1000 | Menus, product variations and page builder saves silently lose data | 3000–5000 |
default_socket_timeout | 60 seconds | Calls to slow external APIs hang for up to a minute | — |
display_errors | On built in · Off in production | With no php.ini, error messages are shown to visitors | Off |
date.timezone | UTC | Times in logs and scheduled tasks look off by hours | Your time zone |
One exception: the PHP command-line binary ignores this limit — max_execution_time is 0 (unlimited) by default in the CLI. That’s why long jobs like imports, reports and cleanups are usually run from cron instead of through a web request. Build the schedule with our cron job generator.
The values are per PHP installation, not per site — unless your host lets you override them per domain, as cPanel’s MultiPHP INI Editor does.
max_input_vars: the limit that fails silently
max_input_vars limits how many form fields PHP accepts in a single request. Above 1,000, PHP doesn’t reject the request — it keeps the first fields and quietly discards the rest.
We tested it. We sent the same form to PHP 8.3 twice: once with 900 fields, once with 1,500.
| Fields sent | Fields PHP kept | What PHP reported |
|---|---|---|
| 900 | 900 | Nothing |
| 1,500 | 1,001 | A warning — “Input variables exceeded 1000” |
499 fields vanished. And the warning only appeared because our test displayed errors. With display_errors = Off — the production default — nothing appears on screen. At best, the warning lands in the error log.
In WordPress, that looks like this:
- A large menu doesn’t save completely. Each menu item sends several fields, so a menu reaches 1,000 fields faster than its item count suggests — and the items at the end disappear after you click Save.
- WooCommerce products lose variations when a product with many of them is saved.
- Page builders save only part of a page — or appear to save and then show older content.
- Plugin settings pages with long forms keep some options and drop others.
The fix is one line in php.ini, .user.ini or your host’s PHP settings:
max_input_vars = 3000If you’ve lost menu items or variations before, check the error log for “Input variables exceeded” — it confirms the cause in seconds.
Memory: PHP’s limit and WordPress’s limit are different
WordPress defines its own memory limits, and they work differently from what most people think. From the WordPress 7.1.2 source code:
WP_MEMORY_LIMITdefaults to 40M on a single site and 64M on Multisite.WP_MAX_MEMORY_LIMITdefaults to 256M — the limit WordPress uses for heavy admin tasks, like processing images and running updates.
The detail that matters: WordPress only raises PHP’s memory limit — it never lowers it. With PHP’s default of 128M, WordPress’s 40M does nothing; the 128M applies. And if the host doesn’t allow the limit to be changed at runtime, WordPress simply uses whatever PHP is set to.
So raising the limit in wp-config.php works only up to what the host allows:
php
define( 'WP_MEMORY_LIMIT', '256M' );If that line has no effect, the ceiling is in PHP’s configuration — raise memory_limit there instead. Our guide to the allowed memory size exhausted error covers the fix step by step.
Uploads: three settings that must move together
An upload passes three PHP checks: upload_max_filesize for each file, post_max_size for the whole request, and max_input_time for how long the upload may take to arrive. Raise one without the others and the error just changes shape — the classic case is WordPress’s “The link you followed has expired”, which is post_max_size being exceeded. Our guide to the upload_max_filesize error walks through each method of raising it.
upload_max_filesize = 64M
post_max_size = 72M
max_input_time = 120PHP isn’t the only layer with an upload limit. Nginx, Apache, ModSecurity and Cloudflare each have their own — see our reference of default request size limits, and our guide to HTTP 413 when an upload fails before reaching PHP.
Time: why max_execution_time isn’t the only clock
max_execution_time counts the time PHP spends executing — on Linux, time spent waiting for a database or an external API usually doesn’t count. So a script can run well past 30 seconds of real time without hitting it, and then be cut off by the web server instead: Nginx’s fastcgi_read_timeout defaults to 60 seconds. Our reference of default timeouts lists every layer. For the six ways to raise it, see our guide to the maximum execution time exceeded error.
How to check your current values
In WordPress: go to Tools → Site Health → Info → Server. It shows the PHP memory limit, max input variables, upload and post limits and the execution time the site is actually running with. Click Copy site info to clipboard and paste it into the checker at the top of this page: it flags the values that are too low and writes the lines to fix them.
Anywhere: create a file with <?php phpinfo(); in the site folder, open it in the browser — and delete it right after, since it exposes your server configuration. The checker above also reads it: select the whole page, copy it and paste it in.
⚠️ Don’t trust php -i in the terminal for website values. The command line often uses a different configuration file from the web server — and max_execution_time is always 0 on the command line.
How to change them
- On shared hosting with cPanel: MultiPHP INI Editor, per domain — no files to edit.
- With a
.user.inifile in the site’s root folder, when PHP runs as FPM or CGI. PHP rereads it every 5 minutes by default, so changes may take a moment to apply. - In
php.ini, on a VPS — then restart PHP-FPM or the web server. - In
.htaccess, withphp_value max_input_vars 3000— only when PHP runs as an Apache module or under LiteSpeed. On PHP-FPM, that line causes a 500 error.
Sources
- PHP: Description of core php.ini directives — PHP Manual
- PHP: php.ini-production — php-src repository
- WordPress: default-constants.php — WordPress 7.1.2 source
On Copahost hosting, memory, upload size, execution time and max_input_vars are adjustable per domain in cPanel’s MultiPHP INI Editor — no support ticket needed. Need full control of php.ini and PHP-FPM? A Copahost VPS gives you root access.
See hosting plans →Frequently asked questions
What is the default max_input_vars in PHP?
1,000. Above that, PHP keeps the first fields of the request and silently discards the rest. In our test with PHP 8.3, a form with 1,500 fields arrived with 1,001 — the other 499 were dropped, with only a warning in the error log.
Why are my WordPress menu items not saving?
Usually because the menu sends more form fields than max_input_vars allows — 1,000 by default. The items at the end are silently dropped. Raise max_input_vars to 3,000 or more, and check the error log for “Input variables exceeded” to confirm.
What is the default memory_limit in PHP?
128M. WordPress sets its own WP_MEMORY_LIMIT of 40M, or 64M on Multisite, but it only ever raises PHP’s limit — never lowers it — so with PHP’s default the 128M applies.
Why does WP_MEMORY_LIMIT not work?
Because WordPress can only raise the memory limit up to what PHP and the host allow. If the host doesn’t let the value be changed at runtime, WordPress uses PHP’s limit regardless of wp-config.php. Raise memory_limit in PHP’s configuration instead.
What is the default upload_max_filesize in PHP?
2M per file, with post_max_size at 8M for the whole request. Raise both together, with post_max_size slightly larger — otherwise WordPress shows “The link you followed has expired”.
How do I check my PHP settings in WordPress?
Go to Tools → Site Health → Info → Server. It shows the memory limit, max input variables, upload and post limits and the execution time the site is actually using. To check them all at once, click Copy site info to clipboard and paste the text into the PHP settings checker at the top of this page.
Conclusion
PHP’s defaults were set for small scripts, not for a WordPress site with a page builder and a thousand-field product form. Most of them fail loudly — a memory error, a timeout, an upload message — and point straight at the setting to change.
max_input_vars is the exception. It drops data without an error on screen, which is why it causes some of the most confusing WordPress problems: menus that won’t save, variations that disappear, pages that revert. If something you saved came back incomplete, check that setting first.
And remember that PHP is one layer among several. Raise memory, uploads and time where your host lets you — and when a limit still won’t move, the ceiling is in the web server or the plan, not in WordPress.
