How to Increase Maximum Execution Time in PHP (4 Practical Methods)

Avatar
M

Maksudur Rahman

Software Engineer••
7812Views
5mRead
0Reactions

If your PHP script halts with Fatal error: Maximum execution time of 30 seconds exceeded, PHP's built-in timeout watchdog killed the process before it could finish.

By default, PHP limits web script execution to 30 seconds to prevent rogue loops or unindexed database queries from exhausting server CPU threads. However, legitimate batch operations—such as generating large PDF reports, parsing 50,000-row CSV spreadsheets, running database migrations, or processing remote Webhooks—regularly need more than 30 seconds.

Here is the quick fix for a single script, followed by production-grade configurations for php.ini, Apache, and Nginx + PHP-FPM.


Quick Answer (For a Single Script)

To increase execution time to 300 seconds (5 minutes) for a specific PHP file without touching global server files, add either of these lines at the very top of your script immediately after <?php:

<?php
// Set maximum execution time to 5 minutes (300 seconds)
set_time_limit(300);

// Alternative syntax using ini_set:
ini_set('max_execution_time', '300');

To allow a CLI batch process or migration to run indefinitely without timing out, pass 0:

<?php
// 0 means unlimited execution time (CLI scripts & background jobs only)
set_time_limit(0);

Warning: Never use set_time_limit(0) on public web routes. If multiple visitors trigger an unthrottled endpoint simultaneously, your PHP-FPM worker pool will starve, locking the entire web server.


Method 1: Change Runtime Limit in PHP Scripts

The set_time_limit() and ini_set() functions are ideal when you do not have root SSH access to your server (such as shared hosting or cPanel), or when only 2 or 3 scripts in your application require a high timeout limit.

<?php
declare(strict_types=1);

// Increase timeout for this specific batch execution
$targetTimeout = 600; // 10 minutes

if (!ini_set('max_execution_time', (string) $targetTimeout)) {
    // Fallback if ini_set is restricted in php.ini disable_functions
    set_time_limit($targetTimeout);
}

// Check the active execution limit
echo "Current execution limit: " . ini_get('max_execution_time') . " seconds\n";

// Run your long process (e.g. processing large data)
processHeavyDataset();

Important Gotcha: CPU Time vs Wall-Clock Time

In Linux and macOS environments, set_time_limit() only counts CPU execution time spent by the PHP interpreter. Time spent waiting for external events—such as sleep(), stream downloads, database network queries via PDO, or remote curl_exec() requests—does not count toward the PHP timeout on Linux. On Windows systems, however, wall-clock time is counted regardless of I/O wait.


Method 2: Global Configuration via php.ini

If you want all PHP scripts across your server to allow longer runs, modify the master php.ini file.

Step 1: Locate Your Active php.ini File

PHP often has multiple php.ini files (one for CLI, one for Apache, and one for PHP-FPM). Run this command in your terminal to find the active configuration:

php --ini

Or create a temporary file with phpinfo() and inspect the Loaded Configuration File row:

php -r "echo php_ini_loaded_file();"

Common paths on Ubuntu/Debian:

  • PHP-FPM: /etc/php/8.3/fpm/php.ini (or 8.2, 8.1)

  • Apache module: /etc/php/8.3/apache2/php.ini

  • CLI: /etc/php/8.3/cli/php.ini

Step 2: Update max_execution_time

Open your php.ini in your editor (with sudo privileges):

sudo nano /etc/php/8.3/fpm/php.ini

Find the max_execution_time directive (press Ctrl + W in nano) and change its value:

; Maximum execution time of each script, in seconds
; Default value: 30
max_execution_time = 300

; Also increase max_input_time if you are uploading massive files
max_input_time = 300

Step 3: Restart Your Web Services

Configuration changes in php.ini do not take effect until PHP workers reload:

# If using PHP-FPM with Nginx or Apache
sudo systemctl restart php8.3-fpm

# If using Apache mod_php
sudo systemctl restart apache2

Method 3: Apache Web Server (.htaccess or VirtualHost)

If your website runs on Apache with mod_php, you can set the limit per directory using your root .htaccess file without restarting Apache:

# Increase PHP execution time to 300 seconds (5 minutes)
<IfModule mod_php.c>
    php_value max_execution_time 300
    php_value max_input_time 300
</IfModule>

# For PHP 8.x running as Apache module:
<IfModule mod_php8.c>
    php_value max_execution_time 300
    php_value max_input_time 300
</IfModule>

Note: If Apache is running PHP via mod_proxy_fcgi (standard in modern Ubuntu / CloudPanel / cPanel setups), .htaccess php_value directives will be ignored or cause a 500 Internal Server Error. In that case, use Method 4 below.


Method 4: Nginx + PHP-FPM (Fixing the 504 Gateway Timeout)

This is the number one reason developers still see timeouts after changing php.ini.

When running Nginx with PHP-FPM, there are three independent timeout layers:

  1. PHP's max_execution_time

  2. PHP-FPM's request_terminate_timeout

  3. Nginx's fastcgi_read_timeout

If you increase PHP's timeout to 300 seconds but leave Nginx at its default 60 seconds, Nginx will cut the connection after 1 minute with: 504 Gateway Time-out: The server didn't respond in time.

flowchart LR
    Client["Browser / Client"] -->|"HTTP Request"| Nginx["Nginx Reverse Proxy"]
    Nginx -->|"FastCGI (fastcgi_read_timeout: 300s)"| FPM["PHP-FPM Worker Pool"]
    FPM -->|"Script Execution (max_execution_time: 300s)"| Script["PHP Script"]

1. Update Nginx FastCGI Timeout

Open your Nginx site configuration file (e.g. /etc/nginx/sites-available/your-domain.conf):

server {
    listen 80;
    server_name example.com;
    root /var/www/example.com/public;

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/var/run/php/php8.3-fpm.sock;

        # Increase FastCGI timeout to 300 seconds
        fastcgi_read_timeout 300;
        fastcgi_send_timeout 300;
        fastcgi_connect_timeout 300;
        
        # Buffer tuning for large responses
        fastcgi_buffers 16 16k;
        fastcgi_buffer_size 32k;
    }
}

2. Update PHP-FPM Pool Configuration

Open your FPM pool configuration (usually /etc/php/8.3/fpm/pool.d/www.conf):

; The timeout for serving a single request after which the worker process will be killed.
; Default is 0 (off), but many setups specify 60s
request_terminate_timeout = 300s

3. Reload Both Services

Test Nginx syntax and reload both services:

sudo nginx -t
sudo systemctl reload nginx
sudo systemctl restart php8.3-fpm

Method 5: Framework Specifics (Laravel & WordPress)

In Laravel Applications

In modern Laravel applications, avoid raising HTTP timeouts on web controllers. Instead, offload any task taking longer than 5 seconds to a background queue:

namespace App\Http\Controllers;

use App\Jobs\ExportLargeReportJob;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;

class ReportController extends Controller
{
    public function generateReport(Request $request): JsonResponse
    {
        // Dispatch heavy execution to Redis / Database Queue worker
        ExportLargeReportJob::dispatch($request->user()->id);

        return response()->json([
            'status' => 'queued',
            'message' => 'Report generation started. You will receive an email once complete.',
        ]);
    }
}

For console commands that genuinely take hours to finish, configure the command timeout directly in app/Console/Kernel.php or CLI execution:

# Run queue worker with 1-hour timeout per job
php artisan queue:work --timeout=3600 --tries=3

In WordPress

Add this directive to the top of your wp-config.php file, right before the line that says /* That's all, stop editing! Happy publishing. */:

// Increase WordPress PHP execution limit
set_time_limit(300);

Frequently Asked Questions

How do I check my current active maximum execution time?

Create a temporary test script or run this in your terminal:

php -r "echo 'Active Timeout: ' . ini_get('max_execution_time') . ' seconds' . PHP_EOL;"

In a web browser, call phpinfo(); and check the max_execution_time directive under the Core module table.

Why does my script still time out after editing php.ini?

There are three common reasons:

  1. You edited the wrong php.ini: Editing /etc/php/8.3/cli/php.ini does not affect web requests served by /etc/php/8.3/fpm/php.ini.

  2. You forgot to restart PHP-FPM: PHP does not read php.ini on every request under FastCGI. Run sudo systemctl restart php8.x-fpm.

  3. Nginx or Cloudflare is terminating the connection: Cloudflare free tiers enforce a hard 100-second HTTP timeout that cannot be overridden by server headers. If your script takes longer than 100 seconds behind Cloudflare, you must stream responses or use a background queue worker.

Can I set max_execution_time to unlimited?

Yes, passing 0 sets the timeout to infinity (set_time_limit(0); or max_execution_time = 0 in php.ini). This is safe and standard for CLI commands, artisan commands, or Cron jobs, but you should avoid it on web-facing HTTP routes to prevent denial-of-service through resource exhaustion.


Summary Checklist

Environment / Layer

Configuration File

Directive

Restart Required?

Single Script

index.php (top of file)

set_time_limit(300);

No

PHP Engine

php.ini

max_execution_time = 300

Yes (PHP-FPM/Apache)

Apache Web Server

.htaccess

php_value max_execution_time 300

No

Nginx Web Server

default.conf / sites-available

fastcgi_read_timeout 300;

Yes (nginx -s reload)

PHP-FPM Pool

www.conf

request_terminate_timeout = 300s

Yes (systemctl restart php-fpm)

Recommended Resources & Courses

Partner Links

React to this article