skip to Main Content

I have a combination of Nginx and PHP-FPM, and I want to set the max execution time on the PHP level to be the same as on Nginx. So I add max_execution_time=30 but it does not work.
If I create an endpoint with the logic like this:

     foreach (range(1, 50) as $i) {
            sleep(1);
            if ($i > 40) {
                $this->logger->error('Processing request', ['i' => $i]);
                continue;
            }

            if ($i > 20) {
                $this->logger->warning('Processing request', ['i' => $i]);
                continue;
            }

            $this->logger->info('Processing request', ['i' => $i]);
        }

        $this->logger->info('Request processed');

and running that script after 30 seconds I see 504 from Nginx, but PHP still processing the request and writing logs. What I’m doing wrong?

Update: sleep here is just an example, on production for long-running endpoints I also see the same issue, when Nginx already interrupted execution but PHP still processing either, executing some query or something else, and I do not want PHP to be busy if it should not be… I know that can be handled on the FPM side by request_terminate_timeout, it’ll SIGTERM process, but in that case, new issues appearing related to PHP workers respawn that lead to an increased amount of 504 that even not reaching PHP at all, and to fix that you need increase amount PHP child processes, which I do not want to do.

2

Answers


  1. Ensure that Nginx’s proxy_read_timeout (or fastcgi_read_timeout) is set to match or exceed your desired maximum execution time in PHP. For example, if you want PHP scripts to run for a maximum of 30 seconds, set Nginx’s timeout to 35 seconds (proxy_read_timeout 35s;). This gives PHP-FPM enough time to complete its work even if it takes the full 30 seconds.

    location ~ .php$ {
        include fastcgi_params;
        fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
        fastcgi_read_timeout 35s;  # Adjust timeout accordingly
    }

    Set Nginx’s proxy_read_timeout (or fastcgi_read_timeout) to a value that accommodates PHP’s max_execution_time plus some buffer.
    Ensure your PHP scripts are optimized to handle timeouts gracefully and efficiently manage long-running tasks.

    Login or Signup to reply.
  2. By default, Nginx does not send a signal to PHP-FPM to terminate the process when a timeout occurs. Nginx simply stops waiting for the response. PHP-FPM continues processing unless it hits its own timeout limits or finishes execution.

    Also, you have to consider the time that the script slept will not count as execution time. So for example the script response takes 60 seconds but the real execution time is maybe 5 seconds.
    for checking real execution time you can use the code below:

    $start_time = microtime(true);
    
    // Define how long the script should run
    $run_time = 10; // in seconds
    
    // Loop until the desired execution time is reached
    while ((microtime(true) - $start_time) < $run_time) {
        // Perform some operations
        for ($i = 0; $i < 10000; $i++) {
            // Simple operations to consume CPU time
            sqrt($i);
        }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search