PHP Maximum Execution Time Exceeded: How to Fix 30-Second Timeout Limits
Learn to diagnose and resolve PHP maximum execution time exceeded errors. Optimize scripts and adjust configuration for long-running PHP processes on web servers.
When your PHP application performs complex tasks, heavy database queries, large file operations, or interacts with slow external APIs, you might encounter a “PHP maximum execution time of 30 seconds exceeded” error. This frustrating timeout prevents your script from completing its work, often resulting in a blank page, an HTTP 504 Gateway Timeout error in the browser, or an error message prominently displayed in your server logs. This guide will walk you through understanding why this occurs and provide precise, step-by-step instructions to resolve it, ensuring your PHP applications can run efficiently.
Symptom & Error Signature
The most common symptom is a web page that loads indefinitely and eventually displays an error in the browser, or a blank page. The error manifests itself in various log files depending on your server configuration.
Typical Browser Output (with Nginx/Apache as proxy):
504 Gateway Timeout
Or simply a blank page with no content.
PHP Error Log (/var/log/php/error.log or similar):
[27-Jun-2026 10:30:05 UTC] PHP Fatal error: Maximum execution time of 30 seconds exceeded in /var/www/html/your-app/index.php on line 123
Nginx Error Log (/var/log/nginx/error.log):
2026/06/27 10:30:05 [error] 1234#1234: *5678 upstream timed out (110: Connection timed out) while reading response header from upstream, client: 192.168.1.1, server: yourdomain.com, request: "GET /long-running-script.php HTTP/1.1", upstream: "fastcgi://unix:/var/run/php/php8.1-fpm.sock:", host: "yourdomain.com"
Apache Error Log (/var/log/apache2/error.log):
[Mon Jun 27 10:30:05.123456 2026] [proxy_fcgi:error] [pid 12345:tid 123456789] [client 192.168.1.1:12345] AH01071: Got error 'PHP message: PHP Fatal error: Maximum execution time of 30 seconds exceeded in /var/www/html/your-app/index.php on line 123'
Root Cause Analysis
The “maximum execution time exceeded” error occurs when a PHP script runs for longer than the configured time limit. This timeout is enforced at multiple layers within a typical web server stack:
-
max_execution_timeinphp.ini: This is the primary PHP directive that dictates how long a script is allowed to run. By default, it’s often set to30seconds. If a script exceeds this, PHP terminates it. -
request_terminate_timeoutin PHP-FPM Pool Configuration: When using PHP-FPM (FastCGI Process Manager), this directive overridesmax_execution_timefor PHP-FPM processes. It defines the maximum time a single request is allowed to process. If exceeded, PHP-FPM will kill the worker process handling the request. -
fastcgi_read_timeoutin Nginx Configuration: Nginx, acting as a reverse proxy, has its own timeout for how long it waits for a response from the FastCGI (PHP-FPM) backend. If PHP-FPM is processing a long request, but Nginx’s timeout is shorter, Nginx might terminate the connection and return a 504 Gateway Timeout even before PHP finishes or hits its own limit. -
Timeoutin Apache Configuration: Similarly, Apache’sTimeoutdirective dictates how long it will wait for various events, including receiving data from a backend likemod_phpormod_proxy_fcgi.
Common Scenarios Leading to Timeouts:
- Inefficient Code: Unoptimized loops, complex calculations, or recursive functions that take too long to complete.
- Heavy Database Operations: Large joins, complex aggregations, or queries on unindexed tables.
- External API Calls: Waiting for responses from third-party services that are slow or unresponsive.
- File Operations: Processing large files, image manipulation, or extensive file I/O.
- Large Data Imports/Exports: Scripts designed to handle significant data transfers without proper chunking or background processing.
- Infinite Loops: While rare, a programming error could cause a script to loop indefinitely.
- Resource Constraints: The server itself might be overloaded, causing scripts to run slower than usual and hit the timeout.
Step-by-Step Resolution
Addressing this error requires a multi-pronged approach: first, investigate and optimize the code, and then, if necessary, adjust server-side timeouts.
1. Analyze Your PHP Script and Application Logs
Before increasing timeouts, understand why your script is taking so long. Indiscriminately increasing limits can mask deeper performance issues and potentially lead to server resource exhaustion.
- Check Application-Specific Logs: Many frameworks (Laravel, Symfony, WordPress) have their own logging mechanisms. These might reveal the specific part of your code that’s causing the delay.
- Profile Your Code: Use tools like Xdebug or Blackfire to get a detailed breakdown of function execution times and memory usage.
- Add Debugging Statements: Temporarily add
error_log()calls at critical points in your script to pinpoint slow sections.
<?php
error_log("Script started at " . date('Y-m-d H:i:s'));
// Simulate a long operation
sleep(10); // Example: database query or API call
error_log("Operation 1 completed at " . date('Y-m-d H:i:s'));
// Simulate another long operation
sleep(25);
error_log("Operation 2 completed at " . date('Y-m-d H:i:s'));
// This part might not be reached if it times out
?>
2. Increase max_execution_time in php.ini
This is the most common PHP-level adjustment.
-
Locate your
php.inifile: For PHP-FPM, it’s typically found in/etc/php/X.x/fpm/php.ini, whereX.xis your PHP version (e.g.,8.1,8.2). If you’re usingmod_phpwith Apache, it might be in/etc/php/X.x/apache2/php.ini.# For PHP-FPM sudo nano /etc/php/8.1/fpm/php.ini # For Apache mod_php sudo nano /etc/php/8.1/apache2/php.ini -
Find and modify the
max_execution_timedirective: Change its value to a more suitable limit, for example,300seconds (5 minutes).; Maximum execution time of each script, in seconds ; http://php.net/max-execution-time max_execution_time = 300[!IMPORTANT] While increasing this value can resolve the immediate timeout, setting it excessively high (e.g.,
0for unlimited) can be dangerous. It allows runaway scripts to consume all server resources, potentially crashing your server. Only increase it as much as genuinely needed after optimizing your code. -
Save the file and restart PHP-FPM or Apache: For PHP-FPM:
sudo systemctl restart php8.1-fpm(Adjust
php8.1-fpmto your specific PHP-FPM service name, e.g.,php7.4-fpm).For Apache
mod_php:sudo systemctl restart apache2
3. Adjust request_terminate_timeout for PHP-FPM
If you are using PHP-FPM (common with Nginx and Apache’s mod_proxy_fcgi), this directive can override max_execution_time for FastCGI requests.
-
Locate your PHP-FPM pool configuration file: This is usually
/etc/php/X.x/fpm/pool.d/www.conf(or another pool file if you have custom pools).sudo nano /etc/php/8.1/fpm/pool.d/www.conf -
Find and modify the
request_terminate_timeoutdirective: Set it to the same or a slightly higher value thanmax_execution_time. A value of0means it will respectmax_execution_time. We’ll set it explicitly to300s for consistency.; The timeout for serving a single request after which the worker process will ; be killed. This option should be used when the 'max_execution_time' PHP ; configuration option does not work as expected for some reason. ; If set to 0, 'max_execution_time' will be used instead. request_terminate_timeout = 300 -
Save the file and restart PHP-FPM:
sudo systemctl restart php8.1-fpm
4. Configure fastcgi_read_timeout in Nginx
If you’re using Nginx as your web server, it needs to wait long enough for PHP-FPM to respond.
-
Locate your Nginx site configuration file: This is typically found in
/etc/nginx/sites-available/yourdomain.conf.sudo nano /etc/nginx/sites-available/yourdomain.conf -
Add or modify the
fastcgi_read_timeoutdirective: Place this directive inside thelocation ~ \.php$block. Set it to a value equal to or greater than yourmax_execution_timeandrequest_terminate_timeout.server { listen 80; server_name yourdomain.com; root /var/www/html/your-app; index index.php index.html index.htm; location / { try_files $uri $uri/ /index.php?$query_string; } location ~ \.php$ { include snippets/fastcgi-php.conf; fastcgi_pass unix:/var/run/php/php8.1-fpm.sock; fastcgi_read_timeout 300s; # <--- Add or modify this line } # ... other configurations ... }[!WARNING] Setting
fastcgi_read_timeoutto an extremely high value without corresponding PHP-FPM timeouts can leave worker processes waiting indefinitely for a broken PHP script. Ensure your PHP timeouts are aligned or shorter. -
Test Nginx configuration and reload:
sudo nginx -t sudo systemctl reload nginx
5. Adjust Timeout in Apache (if applicable)
If you are using Apache with mod_php or mod_proxy_fcgi, you might need to adjust Apache’s Timeout directive.
-
Locate your Apache configuration file: This can be
httpd.conf,apache2.conf, or a specific virtual host file (e.g.,/etc/apache2/sites-available/yourdomain.conf).sudo nano /etc/apache2/apache2.conf # OR sudo nano /etc/apache2/sites-available/yourdomain.conf -
Find and modify the
Timeoutdirective: Its default is usually 300 seconds. Ensure it’s sufficient for your long-running scripts.# Timeout: The number of seconds before receives and sends time out. Timeout 300 -
Save the file and restart Apache:
sudo systemctl restart apache2
6. Optimize PHP Code and Database Queries
This is the most critical and sustainable long-term solution. Increasing timeouts is a workaround, not a fix for inefficient code.
-
Database Optimization:
- Add indexes to frequently queried columns.
- Rewrite complex queries to be more efficient.
- Use
EXPLAINor database profiling tools to identify slow queries. - Fetch only necessary columns, not
SELECT *. - Implement caching for frequently accessed data.
-
Code Efficiency:
- Avoid N+1 queries.
- Refactor inefficient loops and algorithms.
- Stream large file operations instead of loading entire files into memory.
- Cache results of expensive computations.
-
Temporarily Bypass Timeouts (with extreme caution): For very specific, well-understood, non-user-facing scripts (e.g., CLI cron jobs), you can use
set_time_limit(0)at the beginning of your PHP script to disable themax_execution_timelimit.<?php set_time_limit(0); // Disable execution time limit for this script only // Long-running code ?>[!WARNING] Using
set_time_limit(0)for web-facing scripts is highly discouraged. A bug in your script could cause it to run indefinitely, consuming all server resources and potentially crashing your server. It’s only suitable for controlled, background processes.
7. Consider Asynchronous Processing / Background Jobs
For truly long-running tasks (e.g., video encoding, large data imports, sending thousands of emails), it’s best practice to decouple them from the web request cycle.
- Message Queues: Implement a message queue system (e.g., RabbitMQ, Redis Queue, AWS SQS) to push long-running tasks to a queue.
- Workers: Create worker processes (PHP scripts running in the background, managed by
Supervisor,systemd, or a framework’s queue worker) that pull tasks from the queue and process them. - User Feedback: The web interface can immediately acknowledge the request and notify the user that the task is being processed, perhaps updating the status via websockets or polling.
8. Docker/Containerized Environments
If your application runs in Docker containers, the php.ini and PHP-FPM pool configuration files are typically inside the container.
- Access the Container:
docker exec -it <container_id_or_name> /bin/bash - Locate Configuration:
The paths (
/etc/php/X.x/fpm/php.ini,/etc/php/X.x/fpm/pool.d/www.conf) will be relative to the container’s filesystem. - Modify and Restart:
You can either modify them directly within the container (not recommended for production as changes are lost on rebuild/restart) or, preferably:
- Mount Custom Configs: Mount custom
php.inior pool files from your host machine into the container usingdocker-compose.ymlordocker run -v. - Dockerfile: Build a custom Docker image that copies your modified
php.iniduring the build process.
FROM php:8.1-fpm-alpine COPY custom-php.ini /usr/local/etc/php/php.ini COPY custom-www.conf /usr/local/etc/php-fpm.d/www.conf # ... rest of your Dockerfile - Mount Custom Configs: Mount custom
- Restart the Container:
docker restart <container_id_or_name>
By following these steps, you’ll be able to effectively diagnose and resolve PHP maximum execution time exceeded errors, leading to a more robust and performant web application.
