set_time_limit

Sets how many seconds the script may keep running and restarts the timeout counter from zero.

Signature
set_time_limit(int $seconds): bool
  • Added in PHP 4.0

Parameters

ParameterTypeDescription
$secondsintThe maximum execution time in seconds. Zero means no time limit is imposed.

Return value

booltrue on success, or false on failure.

Errors

Fails and returns false when the function has been disabled by disable_functions; the timeout itself raises a fatal error, not a catchable exception. (Safe mode was removed in PHP 5.4, so it plays no part on any supported version.)

set_time_limit() changes the max_execution_time budget for the current script. The detail that surprises people is that it does not add to the remaining time — it resets the counter to zero and starts a fresh window of the length you gave. A script 25 seconds into a 30 second budget that calls set_time_limit(20) ends up running for 45 seconds in total.

What counts toward the limit

Only time spent executing PHP code. On Unix-like systems, waiting on a database query, an HTTP call, a stream read or sleep() does not advance the counter — which is why a script that appears to hang for minutes may never trip the limit at all. Windows is the exception: there the measurement is real elapsed time.

Where it does not help

The CLI SAPI already runs with no time limit, so calling it there is usually pointless. In a web request, the web server has its own timeout — commonly around 60 seconds for Nginx's fastcgi_read_timeout — and it will cut the connection regardless of what PHP thinks. If a job genuinely needs minutes, move it to a queue rather than pushing this number up.

Calling it inside a loop to keep refreshing the budget is a legitimate pattern for long imports.

Example

Example · php
<?php

// set_time_limit() is disabled in this sandbox; this is the usual shape.
echo 'max_execution_time starts at ', ini_get('max_execution_time'), "\n";

set_time_limit(120);                 // fresh 120 second window
echo 'now ', ini_get('max_execution_time'), "\n";

foreach (range(1, 5) as $batch) {
    set_time_limit(30);              // each batch gets its own 30 seconds
    echo "processed batch {$batch}\n";
}

set_time_limit(0);                   // no limit at all
echo 'limit removed: ', ini_get('max_execution_time'), "\n";

When to use it

  • Give a large CSV import or report generator a longer budget than the site default.
  • Refresh the timeout once per batch inside a long processing loop so no single request-wide limit applies.
  • Remove the limit entirely at the top of a maintenance script that legitimately runs for minutes.

Frequently asked questions

Does set_time_limit add to the current time limit or replace it?

It replaces it and resets the counter to zero. Calling set_time_limit(20) twenty-five seconds into a script gives you twenty more seconds from that moment, for a forty-five second total.

Why does my script still time out after set_time_limit(0)?

Because something other than PHP is cutting it off — most often the web server, such as Nginx's fastcgi_read_timeout or Apache's Timeout, or a proxy in front of it. PHP-FPM's own request_terminate_timeout can also override the script setting.

Does sleep() count toward max_execution_time?

Not on Linux or macOS, where only time spent executing PHP code is measured; database queries and stream waits are excluded for the same reason. On Windows the limit is measured as real elapsed time, so sleeping does count there.

More examples

Refresh the budget once per batch

No single chunk needs more than 60 seconds, so resetting the timer each time round means the loop can run indefinitely without ever raising the overall limit. Cannot run here because set_time_limit() is disabled in the sandbox.

Example · php
<?php

$rows = range(1, 10000);

foreach (array_chunk($rows, 1000) as $i => $chunk) {
    set_time_limit(60);   // counter restarts at zero for every chunk
    $sum = array_sum($chunk);
    printf("chunk %d: %d rows, sum %d\n", $i + 1, count($chunk), $sum);
}

echo "import finished\n";

Waiting time does not count on Unix

With a five second limit the script survives an eight second sleep, because on Unix-like systems only CPU time inside PHP is measured. The busy loop afterwards is real execution and does trip the limit. Cannot run here because set_time_limit() is disabled in the sandbox.

Example · php
<?php

set_time_limit(5);
$start = microtime(true);

sleep(8);                      // sleeping does not advance the counter

printf("still alive after %.1f seconds\n", microtime(true) - $start);

$x = 0;
while (microtime(true) - $start < 20) { $x++; }   // this WILL trip the limit
echo "never reached\n";

Report the timeout instead of dying silently

A timeout is a fatal error, so try/catch cannot see it. A shutdown function combined with error_get_last() is the only way to log which job ran out of time. Cannot run here because set_time_limit() is disabled in the sandbox.

Example · php
<?php

set_time_limit(2);

register_shutdown_function(function () {
    $e = error_get_last();
    if ($e !== null && str_contains($e['message'], 'Maximum execution time')) {
        echo "Timed out after {$e['message']}\n";
    }
});

$i = 0;
while (true) { $i++; }

Discussion

  • Be the first to comment on this lesson.