WordPress memory: three limits and the lowest one wins

28/09/2026 · Laurent WordPress in production
WordPress memory: three limits and the lowest one wins

The error names a number. "Allowed memory size of 134217728 bytes exhausted." Somebody adds a line to wp-config.php raising the limit, nothing changes, and they conclude the line does not work.

The line works. It is asking for something the layer below it will not grant.

Three places, and a ceiling

LevelWhereWho can change it
PHP's own limitphp.ini, or the FPM pool configurationThe host, or you if you have the box
Per-directory override.user.ini, or .htaccess on some setupsYou, if the host permits it
WordPress's requestConstants in wp-config.phpYou, always, within PHP's ceiling

The third one is a request, not a setting. WordPress calls into PHP to raise the limit for the current process, and that call cannot exceed what the configuration permits. On hosts that disable the function altogether, the call does nothing at all and reports nothing, which is precisely why editing wp-config.php so often appears to have no effect.

So the order of investigation is bottom-up. Find PHP's ceiling first. Everything above it is theoretical.

The two constants, and what each governs

define( 'WP_MEMORY_LIMIT',     '256M' );
define( 'WP_MAX_MEMORY_LIMIT', '512M' );

They are not a pair of the same thing. The first applies to ordinary front-end requests. The second applies to the administration area and to scheduled tasks, on the reasoning that an import or a bulk operation legitimately needs more room than serving a page does. Core's defaults are 40M and 256M respectively, with a higher front-end default on multisite (WordPress, wp-includes/default-constants.php).

Which means a site that fails in the admin and works on the front end, or the reverse, is telling you which of the two applies, and that is a useful piece of the diagnosis before you touch anything.

Reading the effective value, at the level that matters

Not the panel. The panel shows what the host intends; the process shows what it got.

wp eval 'echo ini_get("memory_limit"), PHP_EOL;'

That gives the command-line value, which is very often different from the web one and is frequently unlimited. So a job that runs perfectly under WP-CLI and dies as a scheduled web request is not a WordPress problem: the command line reads a different configuration file.

For the web value, WordPress will tell you from inside a request:

wp eval 'echo WP_MEMORY_LIMIT, " / ", WP_MAX_MEMORY_LIMIT, PHP_EOL;'

And the site health screen in the administration area reports the effective limit for that request, which is the closest reading to what a visitor's request gets.

Raising it is usually the wrong fix

This is the part that separates a repair from a delay.

PHP does not run out of memory gradually. It runs out because one operation asked for a large amount at once, and in WordPress that operation is nearly always one of four things.

A query with no limit. get_posts or WP_Query with posts_per_page set to -1, on a site whose post count grew. It worked for three years and then the client imported a catalogue. Doubling the memory buys another doubling of the catalogue.

An image being resized. Worth doing the arithmetic once, because it explains most upload failures. An image library decompresses the file into raw pixels: a 6000 by 4000 photograph is 24 million pixels, and at four bytes each that is 96 million bytes of working memory before any thumbnail has been produced. The 3 MB JPEG the client uploaded is 3 MB on disk and around 92 MiB in memory.

An export or an importer holding everything. Building an entire CSV or XML document in a variable before writing it.

A plugin loading its whole dataset on every request. Options that were never meant to be large, autoloaded on every page.

In three of those four, raising the limit means the failure happens later, with more data, in a worse place. The fourth, image processing, is the one where raising it is a legitimate answer, because the requirement is genuinely a fixed lump and there is no way to resize a large photograph in a small budget.

Finding what is actually consuming it

Start with the autoloaded options, because it is one query and it is wrong on a surprising share of client sites:

wp db query "SELECT ROUND(SUM(LENGTH(option_value))/1024/1024, 2) AS mb
             FROM wp_options WHERE autoload='yes';"

wp db query "SELECT option_name, ROUND(LENGTH(option_value)/1024, 1) AS kb
             FROM wp_options WHERE autoload='yes'
             ORDER BY LENGTH(option_value) DESC LIMIT 15;"

Every autoloaded option is read into memory on every single request. A plugin that parked a few megabytes of cached data in there, and left it autoloading after being deactivated, is a permanent tax on every page load. The second query names it in one line.

Then, if the failure is reproducible, get the log to tell you where the last allocation happened. The line named in the fatal error is not the culprit, it is the straw, and reading it as the culprit sends people to rewrite innocent code: the log entry, and how to get one at all.

A reasonable position for a client site

Set the front-end limit at a value the site genuinely needs and no more, so that a runaway fails quickly and visibly rather than consuming the machine. Set the admin and scheduled-task limit higher, because that is where legitimate large operations live. Ask the host what the ceiling is, in writing, and put the answer in the client's file.

Then treat a memory error as a symptom to investigate rather than a number to increase. On shared hosting there is a second reason for that discipline: the account's total process and memory allowance is finite, and a single request permitted to take an enormous amount can cost the whole account, taking down the sites of other clients you host on the same plan.

Back to contents

Share this post.
Stay up-to-date

Subscribe to our newsletter

Don't miss this

You might also like