Your site, an admin screen, an import or a backup stops with one of two PHP errors. The first reads something like Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 20480 bytes). The second reads Fatal error: Maximum execution time of 30 seconds exceeded. Often you do not see either message directly. Visitors get There has been a critical error on this website, a blank white page, a 500 error, or a page builder that spins forever, and the real line is waiting in a log.
Both errors are PHP hitting a safety limit that your hosting account sets. The fix is sometimes as simple as raising the limit, but just as often the limit is doing its job and something on the site is using far more memory or time than it should. This guide shows you how to read the error, check what the limits really are, raise them in the right place for your hosting panel, and find the plugin or task that keeps hitting them. It is for site owners, designers and developers. If you only want the settings and where they live, the PHP settings cheat sheet has them on one page.
What is happening
PHP runs every page request with two budgets. memory_limit caps how much memory one request may use. max_execution_time caps how many seconds one request may run. When a request crosses either line, PHP stops it immediately with a fatal error. Nothing after that point runs, so the page is half built, the import stops mid-file, or the update never finishes.
| Error text |
Which limit |
What the numbers mean |
Allowed memory size of 134217728 bytes exhausted (tried to allocate 20480 bytes) |
memory_limit |
The first number is the limit in bytes (134217728 is 128 MB, 268435456 is 256 MB, 536870912 is 512 MB). The second is the small extra amount PHP asked for when it ran out. It does not tell you how much the request needed in total. |
Maximum execution time of 30 seconds exceeded |
max_execution_time |
The request ran longer than the limit. 30 is PHP’s default for web requests; hosts commonly set 60, 120 or 300. |
Out of memory (allocated 2097152) (tried to allocate 4096 bytes) |
Not memory_limit |
The operating system or the hosting account’s own memory cap refused the request before PHP’s limit was reached. Raising memory_limit will not help; the account itself is out of memory. See the resource limits section below. |
The file and line number at the end of the error are where PHP happened to be when the limit hit. With memory errors that is often a WordPress core file such as wp-includes/class-wpdb.php or wp-includes/functions.php, which does not mean core is broken: it means core was doing work on behalf of something else when the last byte ran out. The plugin responsible is usually found further up the stack trace or by testing, as shown in Step 5.
WordPress has its own memory settings too
WordPress adds two constants on top of PHP’s setting, and this is where most confusion comes from:
WP_MEMORY_LIMIT is what WordPress asks for on normal front-end requests. If you do not set it, WordPress uses 40M (64M on multisite).
WP_MAX_MEMORY_LIMIT is what WordPress asks for in the admin area and for heavy tasks such as image processing. If you do not set it, WordPress uses 256M, or your PHP limit if that is already higher.
The important detail is in WordPress’s own code (wp-includes/default-constants.php): WordPress only ever raises PHP’s memory_limit to match these constants. It never lowers it. So if your host sets 256M and you write define( 'WP_MEMORY_LIMIT', '128M' );, nothing changes; you still get 256M. And if the host has locked memory_limit so scripts cannot change it, WordPress cannot raise it at all, and the constant is ignored. Setting WP_MEMORY_LIMIT to 512M on an account capped at 256M does nothing except mislead the next person who reads wp-config.php.
Before you start
- Access: your hosting control panel, SFTP or the panel’s file manager, and ideally SSH. A WordPress administrator login helps but is not required.
- Backup: reading logs and settings changes nothing. Before editing
wp-config.php, .user.ini or .htaccess, download a copy of the file so you can put it back.
- Where commands run: commands that start with
wp run over SSH in the site folder, the one that contains wp-config.php. On some hosts WP-CLI is called wp-cli. Lines starting with define( are not commands; you paste them into wp-config.php. Words in CAPITALS are placeholders.
- One warning about the command line: PHP on the command line often has different settings from PHP serving your website. The command line usually has no time limit at all, and it may use a different
php.ini or even a different PHP version. Always confirm limits the way the website sees them, as in Step 2.
Step 1: Read the exact error and when it happens
If the site shows only the critical error screen, find the full line first. The recovery mode email WordPress sends to the admin address contains it, and so does the PHP error log. Our critical error guide covers both in detail. The short version: look for “Error log” or “Logs” in your hosting panel, or turn on WordPress logging by adding these lines to wp-config.php above the line that says to stop editing:
define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', true );
define( 'WP_DEBUG_DISPLAY', false );
@ini_set( 'display_errors', 0 );
Paste them as they are; there is nothing to replace. They write errors to wp-content/debug.log without showing them to visitors. Load the failing page once, then read the newest lines over SSH:
grep -E "Allowed memory size|Maximum execution time|Out of memory" wp-content/debug.log | tail -n 20
Where: SSH, site folder. What it does: grep -E keeps only lines matching any of the three phrases, and tail -n 20 shows the last 20. Good output: nothing, which means these errors did not happen since logging started. Bad output: lines with a date, the error, and a file path. Note the time, the URL if it is logged, and the path. Turn WP_DEBUG back to false and delete debug.log when you are finished, because that folder is public.
Then write down when it happens, because that decides the fix:
| When it happens |
Most likely cause |
Go to |
| Every page, suddenly, after an update |
A plugin or theme update with a bug or a loop |
Step 5 |
| Only in the page builder, the block editor or one admin screen |
Admin limit too low for a heavy tool, or a large page |
Steps 2 and 3 |
| Uploading or editing images |
Image processing of very large photos |
Step 6 |
| Imports, exports, backups, migrations |
Long jobs running in a web request |
Step 6 |
| At random, more often when busy |
Account resource limits, cron jobs piling up, or bots |
Step 7 |
| Memory error, and the limit in the message is huge (1 GB or more) |
Infinite loop or runaway query |
Step 5 |
Step 2: Check the limits the website really has
Go to Tools > Site Health > Info in WordPress and open the Server section. It lists the PHP version, memory_limit, max_input_time, max_execution_time, the upload limits and more, exactly as the website sees them. The WordPress Constants section shows WP_MEMORY_LIMIT and WP_MAX_MEMORY_LIMIT. PHP memory limit is what front-end requests get. If WordPress raised it further for the dashboard, a second line, PHP memory limit (only for admin screens), shows that value too.
If wp-admin will not load, check from SSH as the website user:
wp eval 'echo ini_get("memory_limit"), " ", WP_MEMORY_LIMIT, " ", WP_MAX_MEMORY_LIMIT, PHP_EOL;'
php -i | grep -E "^(memory_limit|max_execution_time|Loaded Configuration File|Scan this dir)"
Where: SSH, site folder. What they do: the first line loads WordPress and prints PHP’s memory limit followed by the two WordPress constants. The second prints the command line PHP’s settings and which php.ini files it loaded. How to read it: if the first line prints something like 256M 256M 256M, the site has 256 MB. Remember the command line may differ from the web: if the numbers disagree with Site Health, trust Site Health.
For a quick throwaway check without WordPress, create a file named limits-RANDOM.php in the site folder containing <?php echo ini_get('memory_limit'), ' ', ini_get('max_execution_time');, replacing RANDOM with random letters so nobody can guess it. Open it in your browser, read the two values, and delete the file straight away.
Step 3: Raise the limit in the right place
There are three layers, and a value set in a lower layer is ignored if a higher one forbids it:
- The host’s server configuration. This sets the default and can lock a value so nothing below may change it (in PHP terms, a
php_admin_value in the server or PHP-FPM pool configuration).
- Your account’s PHP settings, set in the control panel, a
.user.ini file, or .htaccess on some servers.
- WordPress, through
WP_MEMORY_LIMIT and WP_MAX_MEMORY_LIMIT, which can only raise memory_limit if layer 1 allows it.
Use your control panel first
| Panel |
Where to change PHP settings |
| cPanel |
Software, MultiPHP INI Editor. Choose the domain in Basic Mode and edit memory_limit and max_execution_time. On CloudLinux hosts the Select PHP Version tool has an Options tab with the same settings, and some hosts prefer that one. |
| Plesk |
Websites & Domains, the domain, PHP Settings (shown as PHP on newer dashboards). memory_limit and max_execution_time are in the performance settings group. |
| DirectAdmin |
Domain Setup, the domain, the PHP Settings page where your host has enabled it. Under PHP-FPM, settings may apply per user rather than per domain, so set them on the account’s main domain. |
| Enhance |
Websites, the website, Advanced, Developer tools, php.ini editor. Add the directive and value, then restart PHP for the website. Enhance’s documentation says each website has its own PHP container and a restart reloads its php.ini, and the site is briefly offline during the restart. |
Menu labels vary by version and host. If yours differ, the hosting control panel cheat sheet maps them side by side.
No panel tool? Use .user.ini or .htaccess
On servers that run PHP as PHP-FPM or FastCGI (most modern hosting), create or edit a file named .user.ini in the site folder:
memory_limit = 256M
max_execution_time = 120
What it does: PHP reads .user.ini files in the folder of the script and each folder above it up to the document root. 256M means 256 megabytes and 120 means 120 seconds. PHP rereads these files only every user_ini.cache_ttl seconds, 300 by default, so wait five minutes before deciding it did not work, then check Site Health again.
On older servers running PHP as an Apache module (mod_php), .user.ini is ignored and .htaccess works instead:
php_value memory_limit 256M
php_value max_execution_time 120
Warning: on a server that does not run mod_php, php_value lines in .htaccess cause an immediate 500 Internal Server Error for the whole site. If that happens, remove the two lines and use .user.ini or the panel instead.
Then set the WordPress constants
Once PHP allows it, tell WordPress to use it. In wp-config.php, above the stop editing line:
define( 'WP_MEMORY_LIMIT', '256M' );
define( 'WP_MAX_MEMORY_LIMIT', '512M' );
What they do: the first sets the front-end request budget, the second the admin and heavy task budget. Pick values your host allows. There is nothing else to replace. Reload Site Health to confirm.
What values are sensible?
There is no single right number, and you should be suspicious of advice to set 1G or unlimited. As a rough guide: 128M is often too low for a site with a page builder, WooCommerce or a membership plugin. 256M covers most sites. 512M is reasonable for the admin area of a large store or a site that edits large images. If a page needs more than that, something is usually wrong, and more memory only makes each runaway request hold more of the server for longer. Never set memory_limit = -1 (no limit) on a live site: one looping request can then take every bit of memory your account has.
For time limits, 60 to 120 seconds is plenty for normal page views. Longer jobs belong on the command line or in background processing (Step 6), not in a page request.
Step 4: When raising the limit does nothing
- The value is locked. If Site Health still shows the old number after the five-minute wait, the host has locked it or caps it by plan. Ask support what the maximum is and how to set it.
- The setting went in the wrong file. A
.user.ini in wp-admin/ or a subfolder only applies to scripts in that folder and below. Put it in the folder that contains wp-config.php. On cPanel, the MultiPHP INI Editor writes its own .user.ini and php.ini files; editing them by hand and through the panel at the same time leads to one overwriting the other.
- The PHP version changed. Each PHP version can have its own settings. If you switched versions, set the limits again for the new one.
- Another timeout fires first.
max_execution_time is only PHP’s timer. The web server, PHP-FPM (request_terminate_timeout), a proxy and Cloudflare each have their own. If you get a 502, 504 or Cloudflare 524 rather than the PHP message, read our guides on 502 and 504 errors and Cloudflare 52x errors. Cloudflare’s documented 524 timeout is not something PHP settings can change.
- The time limit is measured differently than you think. On Linux, PHP’s timer normally counts CPU time used by the script, not time spent waiting on the database, files or a remote API. So a request can hang for minutes waiting on a slow external service without ever hitting
max_execution_time, and then be killed by a web server or proxy timeout instead.
Step 5: Find what is eating the memory or time
If the error started suddenly, or keeps coming back at 256M or 512M, find the cause rather than raising the ceiling again.
Check the most recent change
A plugin or theme update the same day is the prime suspect. Look at Dashboard > Updates, your host’s activity log, or the modification dates of plugin folders:
ls -lt wp-content/plugins | head -n 10
Where: SSH, site folder. -lt lists folders newest first with dates, and head -n 10 keeps the top ten. A folder changed just before the errors began is your first suspect.
Test with plugins switched off
wp plugin list --status=active --skip-plugins --skip-themes
wp plugin deactivate PLUGIN_SLUG --skip-plugins --skip-themes
What they do: the first lists active plugins without loading any plugin code, so the broken one cannot crash the command. The second deactivates one plugin; replace PLUGIN_SLUG with a name from the first list. Deactivate the suspect, retest, and repeat one plugin at a time. If you cannot use WP-CLI, rename the plugin’s folder in wp-content/plugins by adding .off. If the error appears on a specific page only, also try switching the theme to a default one, as described in the critical error guide.
Common heavy hitters
- Page builders on very long pages with many nested sections, global widgets or large saved templates. See our guides for Elementor, Divi and Breakdance.
- Huge autoloaded options. WordPress loads every autoloaded option on every request. A plugin that stores a large log or cache there costs memory on every page. Check the total with
wp db query "SELECT ROUND(SUM(LENGTH(option_value))/1024) AS autoload_kb FROM wp_options WHERE autoload IN ('yes','on','auto-on','auto');", replacing wp_ if your table prefix differs (it is in wp-config.php). A result in the thousands of KB is a problem; our database bloat guide shows how to find and fix the large rows.
- Reports and exports that load every order, post or user at once, such as analytics dashboards, sitemap generators on big sites, and store reports.
- Related posts and broken link checkers that scan the whole site on page load.
- Security scans that read every file in a web request.
- An infinite loop, such as two plugins filtering the same thing back and forth, or a redirect inside PHP. These hit any limit you set, which is the giveaway: the error appears at 256M, at 512M and at 1G.
Step 6: Move long jobs out of the web request
Imports, exports, backups, migrations, search reindexing and bulk image regeneration often need more time or memory than a page request should ever get. Run them where those limits do not apply:
- Use WP-CLI over SSH. The command line normally has no execution time limit. Examples:
wp db export for a database backup and wp media regenerate --only-missing --yes to rebuild missing thumbnails (--only-missing skips images that already have every size, --yes skips the confirmation question). If a command still runs out of memory, prefix it with php -d memory_limit=512M $(which wp) to raise the limit for that one run, where -d sets a PHP setting for that process only.
- Use the plugin’s own batching. Backup and import plugins usually have settings for smaller chunks or split archives. If yours keeps failing, see our guide to backup and migration plugin failures. For big database imports, use the large import guide.
- Images: phone photos of 6000 pixels or more need a lot of memory to resize. WordPress scales down uploads above 2560 pixels, but it has to load the full image to do so. Resize photos before upload, or raise
WP_MAX_MEMORY_LIMIT, which WordPress uses for image work. Our media upload errors guide covers the “Post-processing of the image failed” message that this often causes.
Step 7: Rule out account resource limits
Shared and container hosting puts a memory cap on the whole account as well as on each PHP request. If several heavy requests run at once (a crawler, a backup and the admin), the account can run out even though each request stays under memory_limit. The signs are Out of memory messages, 503 or 508 Resource Limit Is Reached errors, or processes simply disappearing. Check the resource usage or statistics page in your panel (on CloudLinux hosts it is usually called Resource Usage) for memory faults at the times of the errors.
If you see faults, the answer is to reduce concurrent load rather than raise memory_limit: stop aggressive bots (see bots causing high CPU), move WP-Cron to a real cron job so scheduled tasks do not pile up (see WP-Cron not running), add page caching, and schedule backups outside busy hours. If the site has simply outgrown the plan, that is a conversation with your host.
If none of that worked
Contact your host and send:
- The full error lines with dates and times, including your time zone.
- The values Site Health shows for
memory_limit and max_execution_time, and what you tried to set them to and where.
- What triggers it: which page, action or scheduled job.
- Whether it still happens with plugins disabled and a default theme.
- Any resource usage graphs showing memory faults.
Ask them three specific questions: what is the maximum memory_limit my plan allows, is memory_limit or max_execution_time locked for my account, and are there web server or PHP-FPM timeouts shorter than my PHP setting?
Related guides: critical error, white screen of death, upload size limits, max_input_vars and menus not saving and upgrading PHP safely. The wp-config constants reference lists every WordPress constant mentioned here.