request_slowlog_timeout = 1s writes a backtrace of any request still running after a second to the pool's slowlog file, and request_terminate_timeout = 4s kills a worker whose request runs longer. This page waits on a slow API; ?wait=2 produced the slow-log entry below it:
<?php
function fetchRates(): string
{
sleep((int) ($_GET['wait'] ?? 2)); // a slow upstream API
return '{"EUR":0.92}';
}
function buildReport(): array { return json_decode(fetchRates(), true); }
echo json_encode(buildReport()), "\n";[23-Sep-2026 17:17:29] [pool shop] pid 270769 script_filename = /var/www/html/report.php [0x000073b08f014220] sleep() /var/www/html/report.php:4 [0x000073b08f0141b0] fetchRates() /var/www/html/report.php:7 [0x000073b08f0140e0] buildReport() /var/www/html/report.php:8
With ?wait=6, curl 3,008 got a 503 after 4.2 seconds, and the FPM log said execution timed out (4.216206 sec), terminating. The pool's max_execution_time = 2 never fired: on Linux it counts CPU time, and sleep() or waiting on MySQL 524 uses none. Set request_terminate_timeout, which counts wall-clock time, in every pool. pm.status_path = /fpm-status adds a status page (route it to the pool's socket and restrict it to local addresses), read here with ?json while 64 clients hit a dynamic pool of four:
$ curl -s 'http://localhost/fpm-status?json' | jq -c '{"listen queue", "active processes",
"max children reached", "slow requests"}'
{"listen queue":0,"active processes":4,"max children reached":1,"slow requests":0}?full adds each worker's last URI, duration, CPU and memory. max children reached counts only under dynamic and ondemand, and the queue fields come from TCP statistics, so on a Unix socket they stay 0 even under overload, as here.