How to Increase Maximum Execution Time in PHP (4 Practical Methods)
Maksudur Rahman
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 --iniOr 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(or8.2,8.1)Apache module:
/etc/php/8.3/apache2/php.iniCLI:
/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.iniFind 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 = 300Step 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 apache2Method 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),.htaccessphp_valuedirectives will be ignored or cause a500 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:
PHP's
max_execution_timePHP-FPM's
request_terminate_timeoutNginx'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 = 300s3. Reload Both Services
Test Nginx syntax and reload both services:
sudo nginx -t
sudo systemctl reload nginx
sudo systemctl restart php8.3-fpmMethod 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=3In 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:
You edited the wrong
php.ini: Editing/etc/php/8.3/cli/php.inidoes not affect web requests served by/etc/php/8.3/fpm/php.ini.You forgot to restart PHP-FPM: PHP does not read
php.inion every request under FastCGI. Runsudo systemctl restart php8.x-fpm.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 |
|
| No |
PHP Engine |
|
| Yes (PHP-FPM/Apache) |
Apache Web Server |
|
| No |
Nginx Web Server |
|
| Yes ( |
PHP-FPM Pool |
|
| Yes ( |