You trigger a plugin activation, a media upload, or a Site Health check, and WordPress stops with a block of red text that reads roughly:
Fatal error: Allowed memory size of 41943040 bytes exhausted (tried to allocate 8192 bytes) in /home/example/public_html/wp-includes/class-wpdb.php on line 2024
The file path, line number, and byte counts change, but the shape is always the same. PHP asked the operating system for another chunk of memory, the ceiling said no, and the script died mid-request.
What the error actually means
PHP enforces a per-request memory ceiling called memory_limit. When a script tries to allocate one more byte than that ceiling allows, PHP terminates the request and writes a fatal to the log. The long number in the message is the ceiling itself. 41943040 is 40 * 1024 * 1024, which equals 40 MB. The "tried to allocate" number is how much extra the script wanted when it was killed.
Two separate ceilings are in play on a WordPress site, and knowing which one applies decides which fix you reach for first:
- The PHP
memory_limitinphp.ini. This is PHP's own ceiling. The upstream default is128M, but most managed hosts raise it to256Mor512M. This is the hardest cap. Nothing inside WordPress can go above it. - The WordPress
WP_MEMORY_LIMITandWP_MAX_MEMORY_LIMITconstants. WordPress reads both fromwp-config.php. If they are lower thanphp.ini's value, WordPress callsini_set()at boot to raise PHP to that figure. For the full constant reference, see the wp-config.php settings reference. If they are higher than thephp.iniceiling, theini_set()call silently fails and you stay capped at thephp.inivalue. The defaults, coded inwp-includes/default-constants.php, are40Mfor the front-end (64Mfor multisite) and256Mfor thewp-adminarea. That asymmetry is why you sometimes see this error only on the admin side or only on the front-end.
In plain terms: WordPress has its own memory knob, but the PHP knob is the one that actually enforces the ceiling. Raising WP_MEMORY_LIMIT past the host's php.ini value does nothing.
Common causes, most likely first
- A bloated plugin or theme stack loads on every request. The single most common trigger. Every active plugin is loaded and booted on every request, whether it is being used on that page or not. Fifty plugins with sloppy bootstrap code can easily push baseline memory past a 64 MB ceiling before WordPress has done any actual work.
- An image upload or import that needs to decode a large file. PHP's GD and Imagick image handlers load the whole image into memory to resize it. A 6000x4000 JPEG can need 150 to 200 MB of working memory to process, even if the resulting thumbnail is tiny. The error reliably fires mid-upload on under-provisioned sites, and typically surfaces to the user as a vague HTTP error in the media library rather than the fatal message shown here.
- A heavy admin task like Site Health, a plugin update, or a database migration. These run on the admin side where
WP_MAX_MEMORY_LIMITapplies. If yourphp.iniceiling is below 256 MB, the admin-only uplift to 256 MB that WordPress wants to do silently fails, and heavy admin tasks fall back to the lower PHP ceiling. - The site has genuinely outgrown its hosting plan. A WooCommerce store with 30 plugins and a few thousand products running on a 128 MB budget is not misconfigured, it is underpowered. You will see the error under load, not during low-traffic hours.
- A runaway loop or memory leak in a plugin or custom function. Rare, but it looks identical in the log. The tell is that raising the ceiling higher just delays the crash instead of curing it: the script allocates, allocates, allocates, and always dies at whatever the new ceiling is.
Diagnose which cause applies
Before you raise any ceiling, confirm which layer you are actually hitting. Raising WP_MEMORY_LIMIT when the real cap is in php.ini wastes your time. Raising anything on a genuine memory leak wastes your time and your server's memory.
Read the full error line. The file path in the error message tells you which component was on the stack when memory ran out. A path under wp-content/plugins/woocommerce-product-importer/ points at the importer. A path under wp-admin/includes/image.php points at image processing (cause 2). A path inside wp-includes/class-wpdb.php usually means PHP was inside a database call when memory ran out, which on a live site is almost always a much larger loop elsewhere in the request and not the database itself.
Check which side of the site is failing. If the error only fires inside wp-admin, you are bumping against WP_MAX_MEMORY_LIMIT on top of php.ini. If the error fires on public pages, you are bumping against WP_MEMORY_LIMIT. The distinction decides whether fix 1 or fix 2 below is the right starting point.
Check your current ceilings. Drop a tiny diagnostic file in your WordPress root:
<?php
// memory-check.php, delete after use
require __DIR__ . '/wp-load.php';
echo 'php.ini memory_limit: ' . ini_get('memory_limit') . PHP_EOL;
echo 'WP_MEMORY_LIMIT: ' . WP_MEMORY_LIMIT . PHP_EOL;
echo 'WP_MAX_MEMORY_LIMIT: ' . WP_MAX_MEMORY_LIMIT . PHP_EOL;
echo 'current peak: ' . size_format(memory_get_peak_usage(true)) . PHP_EOL;
Visit https://yoursite.nl/memory-check.php and read the four values. Expected output on a healthy site: php.ini memory_limit: 256M, WP_MEMORY_LIMIT: 40M, WP_MAX_MEMORY_LIMIT: 256M, current peak well under any of those. If php.ini memory_limit reads 64M or lower, your host is the bottleneck and fixes 1 and 2 will not help you until the host side is raised. Delete the file after you have read it.
Fix 1: raise WP_MEMORY_LIMIT in wp-config.php
This is the canonical fix when the error fires on the front-end and your php.ini ceiling is already high enough to accommodate a larger WordPress limit. It is a one-line change and it does not depend on Apache, nginx, or the host panel.
-
Download
wp-config.phpover SFTP. Keep the original aswp-config.php.backup. -
Open it and find the line that reads
/* That's all, stop editing! Happy publishing. */. -
Directly above that line, add:
// Raise front-end memory ceiling from the 40M default. define( 'WP_MEMORY_LIMIT', '256M' ); -
Save the file and upload it back to the WordPress root.
The constant has to be defined before wp-settings.php is loaded, which is why it goes above that comment line. Anywhere below it is too late.
Verify: reload the diagnostic file from the previous section. You will know it worked when WP_MEMORY_LIMIT now reads 256M and php.ini memory_limit still reads whatever it was before, that is the expected state. Then retry the original action that caused the error. You will know the fix held when the task finishes without a fatal.
If the diagnostic now reads WP_MEMORY_LIMIT: 256M but the fatal still happens at a value lower than 256 MB, your php.ini memory_limit is the active ceiling and the WordPress constant is being capped beneath it. Go to fix 3.
Fix 2: raise WP_MAX_MEMORY_LIMIT for admin-only errors
If the error only fires inside wp-admin, for example when running Site Health, a plugin update, or a WooCommerce database migration, WP_MEMORY_LIMIT is not the constant you need. The admin area uses WP_MAX_MEMORY_LIMIT instead, and it defaults to 256M. Raising it is the same pattern as fix 1.
-
Open
wp-config.phpagain. -
Above the "That's all, stop editing" line, add:
// Raise admin memory ceiling from the 256M default. define( 'WP_MAX_MEMORY_LIMIT', '512M' ); -
Save and upload.
Do not raise WP_MAX_MEMORY_LIMIT without checking the php.ini ceiling first. If your host caps PHP at 256 MB, setting WP_MAX_MEMORY_LIMIT to 512M quietly accomplishes nothing, and the error will keep firing at 256 MB.
Verify: reload the diagnostic file. You will know it worked when WP_MAX_MEMORY_LIMIT now reads 512M. Then retry the admin task that was failing. You will know the fix held when the task finishes without the fatal. If the fatal still fires at a value lower than 512 MB, the php.ini ceiling is the real cap, go to fix 3.
Fix 3: raise memory_limit in the host control panel
This is the fix that changes the underlying php.ini value that both PHP and WordPress read. On managed hosting, this is the ceiling that governs everything else. If the panel lets you do it, this is the cleanest fix.
- Log into cPanel and open MultiPHP INI Editor (Plesk: PHP Settings, DirectAdmin: PHP Selector, hPanel: PHP Configuration).
- Select the domain whose WordPress site is hitting the error.
- Switch to Editor Mode if your panel offers it, so you can see
memory_limitas a direct value rather than a preset dropdown. - Change it from its current value to
256M. Do not jump straight to1024M. A sky-high ceiling hides real memory leaks rather than fixing them. - Save. Most panels apply the change to the next request with no restart.
Verify: reload the diagnostic file. You will know it worked when php.ini memory_limit now reads 256M. Then retry the action that was failing. You will know the fix held when the task finishes without a fatal.
If the panel does not expose memory_limit, or the value is locked, go to fix 6 and open a support ticket.
Fix 4: raise memory_limit via .htaccess (Apache with mod_php only)
This only works on Apache running PHP as a module (mod_php), and only if your host has not disabled php_value directives in .htaccess. It does not work on nginx. It does not work on Apache with PHP-FPM. On those setups the directive is silently ignored at best, or throws a 500 error at worst.
If you are not sure which SAPI you are on, skip this method and use fix 1 or fix 3. You cannot harm a site by not using .htaccess for this.
-
Download
.htaccessfrom your WordPress root. Keep the original as.htaccess.backup. -
Open it and add this line at the very top of the file, before the
# BEGIN WordPressblock:php_value memory_limit 256M -
Save and upload the file back.
Verify: visit your site's homepage. You will know the directive was accepted when the page loads normally. You will know your host does not support php_value in .htaccess when you instead get a 500 Internal Server Error. If that happens, delete the line you added, restore .htaccess.backup, and use fix 3 or fix 1 instead.
Then reload the diagnostic file. php.ini memory_limit should now read 256M. If it still reads the old value, the directive is being silently ignored because you are on PHP-FPM or nginx. Go to fix 3.
Fix 5: raise memory_limit via .user.ini or php.ini
Some hosting plans support .user.ini overrides, which lets you change the PHP memory_limit from the WordPress root folder without needing a control panel option or server access.
- Open your hosting panel's file manager and navigate to the WordPress root (the same folder that contains
wp-config.php). - Create a new file called
.user.ini. - Add a single line:
memory_limit = 256M. - Save. PHP-FPM rereads
.user.inifiles every 300 seconds by default, so wait up to five minutes before testing.
Verify: reload the diagnostic file after five minutes. You will know it worked when php.ini memory_limit now reads 256M. Then retry the failing action. You will know the fix held when the task finishes.
If .user.ini has no effect after five minutes, your host has disabled per-directory overrides. Use fix 3 instead, or contact your host to raise memory_limit for you.
If you have SSH access: on a VPS or dedicated server where you manage PHP yourself, edit php.ini directly. On Debian/Ubuntu with PHP-FPM the active file is typically /etc/php/8.3/fpm/php.ini (see how to change the PHP version in WordPress for the full upgrade procedure). On RHEL/Alma it is /etc/php.ini. Change memory_limit to 256M and reload PHP-FPM (systemctl reload php8.3-fpm) or Apache (systemctl reload apache2) depending on your SAPI.
When to escalate
If you have tried fixes 1 through 5 and the error still fires, or the fix holds for a day and then comes back, collect this pack before opening a support ticket or handing it to a developer:
- The full error line from the PHP error log, including the file path and line number, and at least three occurrences with timestamps so the pattern is visible.
- The four values from the diagnostic file:
php.ini memory_limit,WP_MEMORY_LIMIT,WP_MAX_MEMORY_LIMIT, and the current peak at the moment the site is idle. - Your WordPress version (Dashboard: Updates), PHP version and SAPI (Tools: Site Health: Info: Server), and hosting plan name.
- A list of the plugins active when the error fires, and which specific action triggers the fatal (plugin activation, media upload, Site Health check, cron job, front-end page load).
- Whether the site is single-site or multisite. The defaults differ.
- The output of Query Monitor's memory panel if you can install it safely. It shows per-plugin memory contribution during a real request and is the fastest way to name the culprit in cause 1.
Two reasons to escalate early instead of raising the ceiling yet again: first, if the fix holds until the next burst of traffic and then fails at the new ceiling, you probably have a leak, not an undersized limit. Second, if the site started working at 256 MB and now needs 512 MB to do the same thing, something changed, and that something is worth identifying before it doubles again.
Prevent the error from coming back
Raising the ceiling is a legitimate fix for a one-off task. It is not a plan for a site that keeps hitting it. Three habits keep memory exhaustion rare:
- Audit the plugin list. Every plugin you remove is memory you get back on every request. Walk through your active plugins and kill anything that is not earning its keep. Query Monitor's memory panel will name the offenders for you if you are not sure. Most WordPress sites run with 10 to 15 active plugins, not 40 to 60.
- Process uploads and imports in batches. If the fatal fires during a large import or a media regenerate, the task is too big for one request, not the server too small. Use WP-CLI for bulk work (
wp media regenerate,wp import), and batch custom imports into chunks of 100 to 500 rows. WP-CLI runs on the php-cli SAPI where the wall clock is effectively gone, and the smaller chunks bring peak memory per request down dramatically. - Match the hosting plan to the workload. A WooCommerce store with 30 plugins needs more memory than a simple blog. If raising the ceiling only buys you a few weeks before the next crash, the site has outgrown the plan, not the limit. Upgrading is cheaper than an outage.
If memory exhaustion is happening in the same workflow that is also producing Maximum execution time of N seconds exceeded, you are almost certainly looking at the same runaway task from two sides: it runs long enough to trip both the memory ceiling and the wall clock. And if memory exhaustion is showing up alongside slow front-end pages and stalled admin dashboards under load, the follow-up symptom is often PHP workers exhausted: each stuck worker holds its allocation open while the queue behind it grows. Finally, when memory exhaustion crashes the site halfway through a request, visitors usually see the "There has been a critical error on this website" message rather than the raw fatal. Those three articles are the sibling reading for this one.