Maximum execution time exceeded
PHP stopped a script that had been running longer than it is allowed to. The limit did its job; the question is whether the job belonged in a web request.
Fatal error: Maximum execution time of 30 seconds exceeded
Work out whether this is a web request or a background job. A page that needs more than thirty seconds has a problem to fix; an import that needs ten minutes needs to run somewhere a timeout does not apply.
What causes it, most likely first.
Work down the list. Each check is written to rule its row in or out before you change anything, because the fixes below it are different and a guess costs more than a command.
| Cause | How to check | Fix |
|---|---|---|
| A bulk job running in the browser | The failure follows an action you started in wp-admin and stops at the same elapsed time each attempt. | Run it from WP-CLI, where the limit does not apply, or in chunks that record progress and resume. |
| An update or install over a slow link | The failure happens while downloading rather than while processing, and larger packages fail while small ones succeed. | Raise the limit for the admin context, or install from the filesystem instead of over HTTP. |
| A slow outbound call inside a page | An ordinary front-end URL is affected and the site depends on a third-party service that is having a bad day. | Bound the outbound request with its own timeout and cache the result, rather than raising the script limit around it. |
| The limit applies where you did not expect it | The value differs between the CLI, the web request and cron - each context can carry a different one. | Change it where the job actually runs. A raised web limit does nothing for a job executing under cron. |
| An infinite loop | The time is spent with no network and no database activity, and the same code path repeats in a profiler. | Fix the loop. Raising the limit here only means the site is stuck for longer before it gives up. |
Fixing it, step by step.
Commands assume WP-CLI and shell access. Where you have neither, each step says what it is doing so it can be done from the dashboard or over SFTP instead.
Find out which limit applies where
The command line and the web request usually do not share a value.
php -i | grep max_execution_time php -r 'echo ini_get("max_execution_time"), PHP_EOL;'Move the job to where the limit does not apply
WP-CLI runs without a wall clock over it, which is why long jobs belong there.
wp plugin install some-plugin --activate
If it must run in a request, raise it for that path only
Scoped to the admin context rather than to everything the site serves.
wp config set WP_MEMORY_LIMIT '256M'
Check whether the time is going outbound
If the script is waiting on somebody else's server, the limit is not the thing to change.
wp eval 'var_dump( wp_remote_get( "https://example.com", [ "timeout" => 5 ] ) );'
Confirm it now finishes
Run the same job again and watch it complete rather than assuming it will.
time wp cron event run --due-now
What the platform takes off the list.
Execution limits are raised for the admin and cron contexts and left where they belong for web requests, so an import has room to finish without also allowing a public page to run for minutes. WP-CLI is available on every plan for the jobs that should never have been in a browser tab, and scheduled work runs on a real scheduler rather than inside somebody's page load.
Questions, answered.
Why is the limit thirty seconds?
Does the limit apply to WP-CLI?
I raised it and the job still fails at the same point.
Is this the same as a 504?
If that was not it.
These fail in ways that look similar from the browser.