How to Configure and Enforce max_execution_time in PHP CLI Scripts


5 views

PHP's CLI SAPI behaves fundamentally differently from web-based PHP execution when it comes to time limits. While web requests automatically inherit the max_execution_time from php.ini (typically 30 seconds), CLI scripts default to unlimited runtime - a design decision documented in PHP's source and bug tracker.

Here are three practical methods to enforce time limits in CLI scripts:

// Method 1: Using set_time_limit()
set_time_limit(60); // 60 seconds maximum

// Method 2: Via ini_set()
ini_set('max_execution_time', 60);

// Method 3: Command-line parameter
// Run as: php -d max_execution_time=60 script.php

The time limit only applies to script execution time - system calls, sleep(), and I/O operations don't count against the limit. For true process termination, consider:

// Combined approach with process checking
$start = time();
set_time_limit(60);

while (true) {
    if (time() - $start > 55) { // Grace period
        die("Time limit approaching - exiting safely");
    }
    // Process data
}

CLI PHP typically loads configuration from these locations (in order):

  1. Command-line -d parameters
  2. /etc/php/cli/php.ini (Linux)
  3. php-cli.ini in PHP binary directory

Verify active settings with:

php -i | grep max_execution_time
php -i | grep 'Configuration File'

For mission-critical scripts, implement a watchdog:

pcntl_signal(SIGALRM, function() {
    exit("Time limit exceeded");
});
pcntl_alarm(60); // 60-second timeout

This POSIX-compliant method works even during blocking operations.

When a CLI script hangs:

  1. Find the process: ps aux | grep php
  2. Check memory usage: top -p [PID]
  3. Graceful termination: kill -15 [PID]
  4. Force kill: kill -9 [PID]

For persistent scripts, consider:

nohup php -d max_execution_time=3600 script.php > output.log &

Working with PHP's Command Line Interface (CLI) presents unique challenges when it comes to execution time limits. Unlike PHP running under Apache or other web servers, the CLI SAPI has max_execution_time hardcoded to 0 (unlimited) by default. This can lead to scripts running indefinitely if not properly managed.

The PHP core team made a deliberate design decision to keep CLI scripts unlimited for several technical reasons:

  • CLI scripts often perform long-running batch operations
  • System administrators need flexibility for maintenance scripts
  • The absence of web server timeouts requires different handling

Method 1: Runtime Configuration

You can enforce time limits directly in your script using either:

// Option 1 - set_time_limit
set_time_limit(30); // 30 seconds

// Option 2 - ini_set
ini_set('max_execution_time', 30);

Important note: These functions only measure PHP execution time. Time spent on:

  • system() calls
  • sleep() functions
  • database queries
  • external processes

is not counted toward the limit.

Method 2: Launch Parameter

When starting your script from command line:

php -d max_execution_time=60 script.php

This approach sets the limit before script execution begins.

Method 3: Custom Timeout Wrapper

For more complex scenarios, implement a wrapper:

class TimeoutEnforcer {
    private $start_time;
    private $time_limit;
    
    public function __construct($seconds) {
        $this->start_time = time();
        $this->time_limit = $seconds;
        register_shutdown_function([$this, 'checkTimeout']);
    }
    
    public function checkTimeout() {
        if ((time() - $this->start_time) >= $this->time_limit) {
            throw new RuntimeException("Maximum execution time exceeded");
        }
    }
}

// Usage:
$enforcer = new TimeoutEnforcer(10); // 10 second limit

When a CLI script hangs, locate it with:

ps aux | grep php

Then terminate forcefully if needed:

kill -9 PROCESS_ID
  • PHP's time limit functions won't interrupt sleep() calls
  • Daemon processes require custom timeout logic
  • Some PHP extensions may ignore time limits
  • Always test timeouts during development

On Unix-like systems, you can wrap your PHP call:

timeout 30s php script.php

This will terminate the process after 30 seconds regardless of PHP's internal state.