155

I am getting 504 timeouts message from nginx when my PHP script is running longer than usual. set_time_limit(0) does not seem to prevent that! Does it not work when running php5-fpm on nginx? If so, whats the proper way of setting the time limit?

Error:

504 Gateway Time-out
nginx/1.2.7
Nyxynyx
  • 61,411
  • 155
  • 482
  • 830

13 Answers13

234

There are several ways in which you can set the timeout for php-fpm. In /etc/php5/fpm/pool.d/www.conf I added this line:

request_terminate_timeout = 180

Also, in /etc/nginx/sites-available/default I added the following line to the location block of the server in question:

fastcgi_read_timeout 180;

The entire location block looks like this:

location ~ \.php$ {
    fastcgi_pass unix:/var/run/php5-fpm.sock;
    fastcgi_index index.php;
    fastcgi_param   SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_read_timeout 180;
    include fastcgi_params;
} 

Now just restart php-fpm and nginx and there should be no more timeouts for requests taking less than 180 seconds.

pymkin
  • 4,304
  • 1
  • 21
  • 18
  • 2
    incase anybody else is wondering, default for mine (nginx + php5-fpm) was 60 seconds, so if you see "gateway timeout" for a script @ 60 seconds, "fastcgi_read_timeout" setting should be added – mn. Oct 19 '13 at 11:37
  • 1
    I have been trying to figure this out for days, and @pymkin's answer is what worked for me. For other amateurs like myself that are wondering how to restart nginx and php5-fpm, run the following two commands: sudo service nginx restart & sudo service php5-fpm restart The only thing I did differently is that I applied these settings to only one of my websites rather than the configuration for all websites on my server. – Pamela Jul 23 '14 at 21:22
  • 5
    Sadly, no matter what I set `fastcgi_read_timeout` to in that `location` block, it still times out after 60 seconds. – Spencer Williams Apr 15 '16 at 15:59
  • 1
    this should be the accepted answer. tried so many solutions but only this works. I was using laravel homestead and had 504 gateway timeout error and this fixed it. – Anbu369 Mar 07 '19 at 12:01
  • 1
    If using Laravel, you need to set this in the `location` block that handles php scripts, rather than the docroot. – Ryan DuVal May 20 '19 at 19:29
  • To add for people using containers and prestashop's offical images, e.g - 1.7-7.3-fpm. To add this configuration to the php.ini in a simple way, get to their github from the dockerhub repository link, in the base/images folder you will find the php.ini file. Copy it locally, make the necessary modification. Create a dockerfile based on prestashop's offical: FROM prestashop/prestashop:1.7-7.3-fpm and in add the relevant file COPY config_files/php.ini /usr/local/etc/php/ . Also take a look at changing max_execution_time and max_input_time, they might be relevant for you. – Pixel Jun 23 '20 at 13:12
  • For people using alpine and PHP 8, the paths are **`/usr/local/etc/php-fpm.d/www.conf`** and **`/etc/nginx/http.d/default.conf`**. – thiagobraga Apr 18 '21 at 19:55
  • This was a LIFESAVER. The fastcgi_read_timeout is what saved me. – Robert Dickey Jul 17 '23 at 18:19
66

Try this link, it has a better solution on how to fix this. So the steps are:

  1. Open your nginx.conf file located in /etc/nginx directory.
  2. Add this below piece of code under http { section:

    client_header_timeout 3000;
    client_body_timeout 3000;
    fastcgi_read_timeout 3000;
    client_max_body_size 32m;
    fastcgi_buffers 8 128k;
    fastcgi_buffer_size 128k;
    

    Note: If its already present , change the values according.

  3. Reload Nginx and php5-fpm.

    $ service nginx reload
    $ service php5-fpm reload
    

    If the error persists, consider increasing the values.

Rayon
  • 36,219
  • 4
  • 49
  • 76
arp
  • 1,358
  • 10
  • 13
  • 2
    This does not make find the cause, it just increases times till the error. But better would be to find solution why it does load so long. When on localhost I am the only client and it loads so long, that not good at all to wait while developing. – Dariux Nov 07 '14 at 07:19
  • 21
    The question isn't asking for a cause of the slow script, it's asking for a way to make the server wait longer. Sometimes you need to run special scripts that do tasks that take a very long time, and that's not a bad thing. – orrd Jul 30 '16 at 22:26
  • Updated (above) link: http://www.codetweet.com/nginx/solved-504-gateway-timeout-error-in-nginx-web-server/ – nadavkav Sep 26 '16 at 18:26
  • 2
    For those who might be wondering what would legitimately take so much time, it could be for example an installation script from a web-interface that attempts to make a connection to a database and then creates many initial tables and fills it with data .. that could take quite some time before a response. – imme Nov 20 '17 at 18:11
  • Keep in mind these global settings will be overridden by per-site settings in `/etc/nginx/sites-available/mysite.com`. – chimit Jun 19 '20 at 08:15
  • Some of those timeouts won't matter without changing the phpfpm side as well (as suggested by other answers). No matter if it resides with NGINX or separately. See other answers for those relevant php config values. – Pixel Jun 23 '20 at 13:03
  • this just killed my nginx or php7.2-fpm, it just stays on reload and never loads. Please explain each value. – mLstudent33 Nov 25 '20 at 06:40
17

You can't use PHP to prevent a timeout issued by nginx.

To configure nginx to allow more time see the proxy_read_timeout directive.

kenorb
  • 155,785
  • 88
  • 678
  • 743
Bart
  • 17,070
  • 5
  • 61
  • 80
  • This solved the issue I was experiencing where 504s would start showing up on my vagrant box (using vaprobash). – Andy Fleming Jun 30 '15 at 00:53
  • 3
    I believe this answer only applies if you're just using Nginx as a proxy server. This wouldn't work if you're using Nginx as your primary web server (with PHP-FPM). – orrd Aug 02 '16 at 21:30
16

The correct answer is increasing fastcgi_read_timeout in your Nginx configuration.
Simple as that!

tfont
  • 10,891
  • 7
  • 56
  • 52
16
 sudo nano /etc/nginx/nginx.conf

Add these variables to nginx.conf file:

http {  
  # .....
  proxy_connect_timeout       600;
  proxy_send_timeout          600;
  proxy_read_timeout          600;
  send_timeout                600;
}

And then restart:

service nginx reload
anjaneyulubatta505
  • 10,713
  • 1
  • 52
  • 62
kabus
  • 899
  • 1
  • 11
  • 20
11

There are three kinds of timeouts which can occur in such a case. It can be seen that each answer is focused on only one aspect of these possibilities. So, I thought to write it down so someone visiting here in future does not need to randomly check each answer and get success without knowing which worked.

  1. Timeout the request from requester - Need to set timeout header ( see the header configuration in requesting library)
  2. Timeout from nginx while making the request ( before forwarding to the proxied server) eg: Huge file being uploaded
  3. Timeout after forwarding to the proxied server, server does not reply back nginx in time. eg: Time consuming scripts running at server

So the fixes for each issue are as follows.

  1. set timeout header eg: in ajax

    $.ajax({
        url: "test.html",
        error: function(){
            // will fire when timeout is reached
        },
        success: function(){
            //do something
        },
        timeout: 3000 // sets timeout to 3 seconds
    });
    
  2. nginx Client timeout

    http{
         #in seconds
        fastcgi_read_timeout 600;
        client_header_timeout 600;
        client_body_timeout 600;
     }
    
  3. nginx proxied server timeout

    http{
      #Time to wait for the replying server
       proxy_read_timeout 600s;
    
    }
    

So use the one that you need. Maybe in some cases, you need all these configurations. I needed.

A.L
  • 10,259
  • 10
  • 67
  • 98
Gayan Kavirathne
  • 2,909
  • 2
  • 18
  • 26
1

You need to add extra nginx directive (for ngx_http_proxy_module) in nginx.conf, e.g.:

proxy_read_timeout 300;

Basically the nginx proxy_read_timeout directive changes the proxy timeout, the FcgidIOTimeout is for scripts that are quiet too long, and FcgidBusyTimeout is for scripts that take too long to execute.

Also if you're using FastCGI application, increase these options as well:

FcgidBusyTimeout 300
FcgidIOTimeout 250

Then reload nginx and PHP5-FPM.

Plesk

In Plesk, you can add it in Web Server Settings under Additional nginx directives.

For FastCGI check in Web Server Settings under Additional directives for HTTP.

See: How to fix FastCGI timeout issues in Plesk?

kenorb
  • 155,785
  • 88
  • 678
  • 743
1

Don't forget to look into your php-fpm logs !

In my case on PHP 7.3 I encountered:

WARNING: [pool www] server reached pm.max_children setting (5), consider raising it

On /etc/php/7.3/fpm/pool.d/www.conf I had to raise the pm.max_children value from 5 up to 50 (I do pretty heavy local stuff sometimes...).

Note: be aware that it may use much more CPU !

AnomalySmith
  • 597
  • 2
  • 5
  • 16
0

Since you're using php-fpm you should take advantage of fastcgi_finish_request() for processing requests you know can take longer.

Kate
  • 712
  • 3
  • 6
  • 23
0

Using set_time_limit(0) is useless when using php-fpm or similar process manager.

Bottomline is not to use set_time_limit when using php-fpm, to increase your execution timeout, check this tutorial.

kenorb
  • 155,785
  • 88
  • 678
  • 743
  • 8
    may be provide some explanation of the answer here as well as this answer may become obselete if link expires. – Lakshmi Jun 27 '14 at 08:29
0

After high hours looking for answers with this problem, I see one thing.

There are one more layer into my application:

  1. Load balancer (the problem was all the time here)
  2. Webserver (nginx)
  3. Application (php)

Escaping from make request to LB, I can see the success response on test with "sleep" in php.

RSiqueira
  • 91
  • 2
  • 5
0

For my case, I had all possible TimeOut set correctly around 60s, but still got that 504 Gateway timeout error, then I was wondering why it always timeout around 15s after checking the request in my browser console !

After checking my other Apache2 config files, it turns out that "15s" was just sitting there in the file qos.conf (from the Quality of Service module) in the TimeOut option ! so I just changed it to 30 and my problem was solved (in fact, the request just needed about 19s to finish, so it was too close). I hope this helps someone if nothing else works.

Youssef
  • 132
  • 2
  • 2
  • 10
0

Go into server

sudo nano /etc/nginx/nginx.conf

Add configuration in the HTTP section for the status of 504 (Gateway Time-out) as under:

proxy_read_timeout 3600;

Then restart the server of Nginx and it's working fine

sudo systemctl restart nginx
CHAVDA MEET
  • 777
  • 8
  • 14