Fixing timeout between Nginx and PHP-FPM

Sysadmin

In case you’ve set up Nginx as reverse proxy for PHP-FPM and you have very slow or complex PHP script that executes for quite some time, you’ve probably seen an 504 gateway time-out error. This is pretty common error, but in most cases people are barking at the wrong tree and they’re having difficulties finding out which timeout directive is the right one for their scenario.

I’ve seen some people desperately experimenting with proxy_read_timeout, send_timeout, even client_header_timeout and client_body_timeout directives, but if they bothered to take a peek into Nginx’s error_log, they would’ve seen an error such as:

2013/01/19 11:36:59 [error] 14564#0: *1215
upstream timed out (110: Connection timed out) while reading response header
from upstream, client: 123.456.789.123, server: example.com, request:
"POST /path/to/some/script.php HTTP/1.1", upstream: "fastcgi://127.0.0.1:9000",
host: "example.com", referrer: "http://example.com/"

The error clearly states that connection timed out between Nginx and upstream server - in this case PHP-FPM, but that could be any FastCGI server - while reading response header. If you put 2 and 2 together, you just can’t miss the fastcgi_read_timeout directive. Quick glance at the documentation reveals what this directive does:

Directive sets the amount of time for upstream to wait for a fastcgi process to send data. Change this directive if you have long running fastcgi processes that do not produce output until they have finished processing. If you are seeing an upstream timed out error in the error log, then increase this parameter to something more appropriate.

So, adding this directive with high enough value to http, server or location context would be a smart move. For example:

location ~* \.php$ {
    include         fastcgi_params;
    fastcgi_index   index.php;
    fastcgi_read_timeout 120;
    fastcgi_pass    127.0.0.1:9000;
    fastcgi_param   SCRIPT_FILENAME    $document_root$fastcgi_script_name;
}