Runtimes Intermediate

Resolving PHP Maximum Execution Time Exceeded on Ubuntu 20.04 LTS (30 Seconds Timeout)

Troubleshoot and resolve the common 'PHP maximum execution time of 30 seconds exceeded' error on Ubuntu 20.04 LTS servers. Learn to adjust PHP-FPM and Nginx timeouts effectively for long-running scripts.

πŸ‘¨β€πŸ’»
Senior Systems Architect • Verified in Staging Labs

Troubleshoot and resolve the common 'PHP maximum execution time of 30 seconds exceeded' error on Ubuntu 20.04 LTS servers. Learn to adjust PHP-FPM and Nginx timeouts effectively for long-running scripts.

Introduction

As a seasoned Systems Administrator, encountering a "PHP maximum execution time exceeded" error is a common scenario when dealing with web applications, especially those performing resource-intensive tasks. This error typically manifests as a blank page, a generic "500 Internal Server Error," or a specific PHP error message directly in your browser. It signifies that a PHP script has taken longer to execute than the predefined limit, causing the web server or PHP-FPM process to terminate it prematurely.

This guide will walk you through diagnosing and resolving the PHP maximum execution time of 30 seconds exceeded timeout on an Ubuntu 20.04 LTS server, focusing on environments utilizing PHP-FPM with Nginx as the web server.

Symptom & Error Signature

When this timeout occurs, users may see different outputs depending on the web server configuration and PHP error reporting settings.

1. Browser Output:

  • A blank white page.
  • A generic "500 Internal Server Error" message.
  • "This page isn’t working" or similar browser-specific error.

2. PHP-FPM Error Log (/var/log/phpX.X-fpm.log or site-specific logs): You'll typically find entries indicating that a PHP-FPM child process was killed:

[DD-Mon-YYYY HH:MM:SS] WARNING: [pool www] child XXXXX exited on signal 9 (SIGKILL) after 30.012345 seconds from start
[DD-Mon-YYYY HH:MM:SS] NOTICE: [pool www] child XXXXX started

Or, if display_errors is off and log_errors is on, you might see the specific PHP fatal error:

[DD-Mon-YYYY HH:MM:SS UTC] PHP Fatal error: Maximum execution time of 30 seconds exceeded in /path/to/your/script.php on line X

3. Nginx Error Log (/var/log/nginx/error.log): Nginx, acting as a proxy to PHP-FPM, will report an upstream timeout if PHP-FPM doesn't respond within its own configured limits:

YYYY/MM/DD HH:MM:SS [error] XXXXX#XXXXX: *XX upstream timed out (110: Connection timed out) while reading response header from upstream, client: X.X.X.X, server: yourdomain.com, request: "GET /long-script.php HTTP/1.1", upstream: "fastcgi://unix:/var/run/php/php7.4-fpm.sock:", host: "yourdomain.com"

Root Cause Analysis

The "PHP maximum execution time exceeded" error is a multi-faceted problem often involving several configuration layers:

  1. max_execution_time in php.ini: This is the primary PHP directive that sets the hard limit for how long a script is allowed to run. Its default value is often 30 seconds. If a PHP script exceeds this time, the PHP engine itself will terminate it.
  2. request_terminate_timeout in PHP-FPM Pool Configuration: PHP-FPM has its own timeout setting per pool. This dictates how long PHP-FPM will wait for a child process to finish processing a request before forcefully killing it. If this value is less than or equal to max_execution_time and the script runs longer, PHP-FPM might kill the process before PHP's internal timer does, or at the same time.
  3. Web Server (Nginx) FastCGI Timouts: Nginx, when communicating with PHP-FPM via FastCGI, also imposes its own set of timeouts (e.g., fastcgi_read_timeout, fastcgi_send_timeout, fastcgi_connect_timeout). If these timeouts are shorter than the combined PHP and PHP-FPM limits, Nginx will close the connection and report an upstream timeout, even if PHP-FPM is still processing the request.
  4. Inefficient Script Logic: While increasing timeouts can resolve the immediate error, the underlying issue might be an unoptimized PHP script. Tasks like large data imports, complex image manipulations, or recursive functions without proper termination conditions can legitimately take a long time, signaling a need for code optimization, asynchronous processing, or background jobs.
  5. Resource Bottlenecks: High server load, insufficient CPU, memory, or slow disk I/O can cause scripts to take longer than usual, pushing them over the execution time limit.

To properly resolve this, you need to adjust the timeout settings across all three layers: php.ini, PHP-FPM pool configuration, and Nginx.

Step-by-Step Resolution

Follow these steps to systematically increase the timeout limits across your server stack. We will aim for a 120 second timeout as a common starting point, which can be further adjusted.

1. Identify Your PHP Version and Configuration Files

First, determine which PHP version is active and where its configuration files are located.

# Check PHP CLI version
php -v

# Output example:
# PHP 7.4.33 (cli) (built: ... ) (NTS)
# Copyright (c) The PHP Group
# Zend Engine v3.4.0, Copyright (c) Zend Technologies
#     with Zend OPcache v7.4.33, Copyright (c), by Zend Technologies

# Find the active php.ini file for FPM
# Replace X.X with your PHP version (e.g., 7.4, 8.1)
sudo find /etc/php -name php.ini | grep fpm

This will typically show /etc/php/X.X/fpm/php.ini. The PHP-FPM pool configuration file will usually be at /etc/php/X.X/fpm/pool.d/www.conf (for the default www pool) or a custom .conf file if you have multiple pools.

2. Increase max_execution_time in php.ini

This is the most fundamental PHP setting to modify.

# Replace X.X with your PHP version (e.g., 7.4, 8.1)
sudo nano /etc/php/X.X/fpm/php.ini

Locate the max_execution_time directive and change its value. For this guide, we'll set it to 120 seconds.

; Maximum execution time of each script, in seconds
; https://php.net/max-execution-time
max_execution_time = 120

While increasing this limit, remember that very long execution times can indicate inefficient code or a potential for denial-of-service attacks. Consider the optimal balance between application needs and server stability. A value between 60-300 seconds is common for intensive tasks, but anything beyond that usually points to architectural issues.

3. Adjust PHP-FPM request_terminate_timeout

This setting controls how long PHP-FPM will wait for a script to finish before killing the worker process. It should be set to a value equal to or slightly greater than max_execution_time.

# Replace X.X with your PHP version
sudo nano /etc/php/X.X/fpm/pool.d/www.conf

Find the request_terminate_timeout directive. It might be commented out; uncomment it and set its value.

; 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' ini option
; does not stop the script for some reason. If set to '0', 'max_execution_time'
; will be used instead.
; Default Value: 0
request_terminate_timeout = 120s

Setting request_terminate_timeout = 0 effectively disables this timeout, making PHP-FPM rely solely on max_execution_time. While this might seem convenient, it can lead to hung PHP-FPM processes if PHP itself fails to terminate a script (e.g., due to an infinite loop in a C extension). It's generally safer to have a definite timeout at the FPM level.

4. Configure Nginx FastCGI Timouts

Nginx needs to be configured to wait long enough for PHP-FPM to respond. These settings are typically found in your site's Nginx configuration file.

# Adjust this path to your specific site configuration
sudo nano /etc/nginx/sites-available/yourdomain.com.conf

Inside the location ~ .php$ block, add or adjust the fastcgi_read_timeout, fastcgi_send_timeout, and fastcgi_connect_timeout directives. These should be at least as long as your max_execution_time and request_terminate_timeout.

server {
    listen 80;
    server_name yourdomain.com www.yourdomain.com;
    root /var/www/yourdomain.com/public;
    index index.php index.html index.htm;

    location / {
        try_files $uri $uri/ /index.php?$args;
    }

    location ~ .php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/var/run/php/phpX.X-fpm.sock; # Replace X.X with your PHP version
        
        # Add or adjust these lines:
        fastcgi_read_timeout 120s;
        fastcgi_send_timeout 120s;
        fastcgi_connect_timeout 120s;
    }

    # ... other configurations ...
}

If you have global Nginx proxy_read_timeout, proxy_send_timeout, or proxy_connect_timeout directives in your http or server blocks, ensure they are also at least as long as your desired PHP execution time. For direct FastCGI connections, fastcgi_read_timeout is the most critical.

5. Restart Services

After making configuration changes, you must restart both PHP-FPM and Nginx for the new settings to take effect.

# Restart PHP-FPM (replace X.X with your PHP version)
sudo systemctl restart phpX.X-fpm

# Restart Nginx
sudo systemctl restart nginx

Always restart services after modifying their configuration files. Failure to do so will result in the old settings remaining active. You can verify the status with sudo systemctl status phpX.X-fpm and sudo systemctl status nginx.

6. Verify Configuration

To confirm your changes, create a small phpinfo.php file in your web root:

<?php
phpinfo();
?>

Access this file via your browser (http://yourdomain.com/phpinfo.php) and search for max_execution_time. You should see your new value (e.g., 120).

Then, re-test the script that was causing the timeout. Monitor your Nginx and PHP-FPM error logs (/var/log/nginx/error.log and /var/log/phpX.X-fpm.log) for any new errors or indications that the script successfully completed.

7. Consider Script Optimization (Optional but Recommended)

While increasing timeouts resolves the immediate error, it's a workaround, not a solution, for fundamentally inefficient code. For tasks that genuinely take a very long time, consider:

  • Breaking down tasks: Divide large operations into smaller, manageable chunks.
  • Asynchronous processing: Use message queues (e.g., RabbitMQ, Redis Queue) and background workers (e.g., via Supervisor, Systemd) to process long-running tasks outside of the user's web request.
  • Cron jobs: Schedule heavy data processing or cleanup tasks to run at off-peak hours using cron.
  • Code optimization: Profile your PHP script to identify bottlenecks (e.g., slow database queries, inefficient loops, excessive API calls) and optimize them.

By following these steps, you can effectively resolve the "PHP maximum execution time exceeded" error on your Ubuntu 20.04 LTS server, ensuring your web applications can handle necessary long-running operations.

πŸ‘¨β€πŸ’»

Johnathon Wheeler

Senior Systems Architect & DevOps Engineer • Austin, TX

Connect on LinkedIn →

Johnathon has over 16 years of hands-on experience designing, debugging, and scaling Linux web hosting stacks, container clusters, and high-availability database architectures. Every guide on ButItWorkedLocal is independently tested against Debian 12, Ubuntu 24.04/22.04 LTS, Rocky Linux, and Docker environments to guarantee reproducibility in production.

πŸ›‘οΈ

Our Production Verification Guarantee

Encountering a bug not covered here or running a non-standard kernel configuration? Our solutions are continually refined against real production incidents. Submit an environment trace for our editorial team to replicate.