Troubleshooting Nginx Upstream Timeout: 504 Gateway Error
When your Nginx server acts as a reverse proxy, it sits between the client and a backend application like PHP-FPM, Node.js, or Python. An Nginx upstream timeout occurs when Nginx sends a request to this backend but waits too long for a response. After a specific limit, default is 60 seconds, Nginx gives up, closes the connection, and serves a 504 Gateway Time-out error to the user.
In this guide from PerLod Hosting, you will learn the root causes of Nginx upstream timeout error, the essential settings to fix it, and validate your fixes.
Table of Contents
Why You Get Nginx Upstream Timeout 504 Error?
A 504 error usually isn’t Nginx’s fault; it happens when the backend system, like your database or app, is too slow. To fix it permanently, you must find out what is causing that delay.
Here are the most common Nginx upstream timeout causes:
Slow Application Logic: If a script performs heavy data processing, rendering, or API calls that exceed the default 60 seconds, Nginx will cut the connection before the work is finished.
Database Bottlenecks: This is the most common cause. If your MySQL or PostgreSQL database has locked tables, slow queries, or high I/O wait times, the application waits for the database, and Nginx waits for the application.
Resource Exhaustion: If your server lacks CPU or RAM, or if the PHP-FPM worker pool is saturated, new requests are queued. If they sit in the queue longer than the timeout threshold, they fail.
Network Latency: In distributed setups where Nginx and the backend are on different servers, network congestion or firewall rules can drop packets, leading to connection timeouts.
Understand Nginx Upstream Timeout Settings
To control how Nginx handles slow backends, you must configure specific directives. Note that there are two sets of directives depending on your upstream type, including proxy_ for general backends like Node.js, Python, and Go, and fastcgi_ for PHP-FPM.
General Proxy Settings Include:
- proxy_read_timeout: It is the most critical setting, which determines how long Nginx waits for the backend to send data after the connection is established. The default is 60 seconds.
- proxy_connect_timeout: Defines how long Nginx waits to establish the initial handshake with the upstream server.
- proxy_send_timeout: Sets the timeout for transmitting the request to the upstream server.
PHP-FPM Settings Include:
- fastcgi_read_timeout: It is similar to proxy_read_timeout but specifically for the FastCGI protocol used by PHP. If you are serving a WordPress or Laravel site, this is the directive that matters.
Now that you have understood these settings, proceed to the next step to apply the best fixes for Nginx upstream timeout 504 errors.
How To Fix Nginx 504 Errors?
Fixing Nginx 504 errors includes three processes:
- Tracing the error
- Optimizing the bottleneck
- Adjusting timeouts
Follow the steps below to fix Nginx 504 errors.
Step 1: Trace the Error in Logs
Before changing the timeout configurations, you must confirm the error source. You can use the command below to watch your Nginx error log in real-time:
tail -f /var/log/nginx/error.log | grep "upstream timed out"
You will receive messages like this:
upstream timed out (110: Connection timed out) while reading response header from upstream
If the error appears immediately, it is a connection failure; if it takes exactly 60 seconds, it is a read timeout.
Tip: To dig deeper into latency issues before they become timeouts, learn how to identify Nginx slow requests.
Step 2: Fix the Root Cause
Increasing the timeout is only a temporary fix; you should solve the actual performance issue first. Here are the most common recommendations:
Optimize Database: Enable the Slow Query Log in MySQL or PostgreSQL to find queries taking longer than 1 to 2 seconds and add indexes.
Scale Workers: If using PHP-FPM, you must check your pm.max_children setting. If it’s too low, increase it to handle more concurrent requests. For detailed configuration tuning, you can check this guide on Optimizing Nginx and PHP-FPM on VPS.
Upgrade Infrastructure: If your CPU is constantly at 100% usage during these timeouts, your hardware may be insufficient. Upgrading to a high-performance VPS server can provide the dedicated CPU cores and RAM needed to process requests faster.
Step 3: Adjust Nginx Timeout Configuration
If your app handles heavy tasks like big reports that take over 60 seconds, you must increase the timeout values.
To do this, open your Nginx config file in /etc/nginx/nginx.conf or a site-specific file in /etc/nginx/sites-available/ and adjust the settings:
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://127.0.0.1:3000;
# Increase timeout to 300 seconds (5 minutes)
proxy_read_timeout 300;
proxy_connect_timeout 300;
proxy_send_timeout 300;
}
For PHP-FPM users:
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
# Increase FastCGI timeout to match PHP max_execution_time
fastcgi_read_timeout 300;
}
}
Important Note: If you increase fastcgi_read_timeout, you must also update your php.ini file. Find max_execution_time and set it to match, for example, max_execution_time = 300; if not, PHP will kill the script before Nginx times out.
Validate Nginx Upstream Timeout Configuration
After you applied the fixes, you must verify the configuration and monitor the results to ensure the Nginx 504 errors have stopped.
First, ensure there are no typos in your config file with the command below:
nginx -t
In your output, you must see that the syntax is OK, and the test is successful.
Then, reload Nginx to apply the changes without dropping active connections:
systemctl reload nginx
Finally, you can modify your Nginx logging format to track exactly how long upstream servers take to respond. Add $upstream_response_time to your log_format in nginx.conf:
log_format upstream_time '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent"'
' rt=$request_time uct="$upstream_connect_time" uht="$upstream_header_time" urt="$upstream_response_time"';
This helps you see if requests are slow to process or stuck trying to connect, which confirms if your fix worked.
FAQs
What is the difference between 502 Bad Gateway and 504 Gateway Timeout?
A 502 Bad Gateway means the backend crashed, sent an invalid response, or rejected the connection immediately. A 504 Gateway Timeout means the backend is working, but taking too long to reply.
Why do I get Nginx 504 errors only during high traffic?
This signals resource exhaustion. When your database or PHP-FPM hits its limits during traffic spikes, requests get queued. If they wait in the queue longer than 60 seconds, Nginx times them out.
Does increasing the Nginx timeout affect server performance?
Increasing timeouts keeps connections open longer, consuming more RAM and workers. If too many users wait, your server may crash from resource exhaustion, so optimizing code is safer than extending timeouts.
Conclusion
Nginx upstream timeouts are a symptom of slow application performance rather than a server configuration fault. While increasing proxy_read_timeout or fastcgi_read_timeout provides an immediate fix for long-running tasks, the permanent solution is in optimizing your database queries and scaling your backend resources.
By tracing errors through logs and validating your fixes with specific timeout directives, you ensure your VPS server remains responsive even under heavy load.
We hope you enjoy this guide. Subscribe to our X and Facebook channels to get the latest updates and articles.