PHP Timeouts

If you have a web PHP script that takes longer than five minutes to run, you may experience “timeouts” (sometimes shown in the error logs as a “Premature end of script headers” message or as a request that generates a “500 Internal Server” error after 300, 660, or 1800 seconds).

You’ll have this problem if:

  • Your script doesn’t output the “HTTP headers” within 5 minutes; or
  • Your script doesn’t send and flush data at least once every 10 minutes; or
  • Your script runs for more than 30 minutes.

Solving the problem

If your web script runs for more than 30 minutes, you’ll simply have to modify it to finish in less time: like most shared hosting companies, we don’t support longer running web scripts, unfortunately.

If your script runs for between 5 and 30 minutes but has this problem, there are different ways you can solve it.

The first is to add these two lines to your php.ini settings to automatically flush data every time it’s written:

output_buffering = 0
implicit_flush = 1

This will help if the problem is that your script is writing small amounts of data at least once every ten minutes but isn’t flushing it. (If you do this and you’re using FastCGI, “output_buffering = 0” by itself won’t help, because PHP always uses an invisible 8KB extra layer of output buffering under FastCGI. You do need the “implicit_flush = 1” line, too.)

The second choice is to modify your script to ensure that it flushes data by calling both ob_flush and flush at least once every ten minutes.

A simple example will illustrate this. This script will timeout under FastCGI (and also without FastCGI if output_buffering is enabled) if you haven’t modified your php.ini settings:

<?php
    for ($i = 1; $i <= 25; $i++)
    {
      print ($i);
      sleep (60);
    }
?>

However, this script will not timeout because of the ob_flush and flush lines:

<?php
    for ($i = 1; $i <= 25; $i++)
    {
      print ($i);
      ob_flush();
      flush();
      sleep (60);
    }
?>

Technically speaking, you only need to call ob_flush and flush within the first five minutes of the script running, and then at least once every 10 minutes. However, it’s usually easier to just put them in the script at a convenient place without worrying about the details: the lack of output buffering will have no measurable performance impact on a script that already takes minutes to run.