504 Gateway Timeout: What It Means and How to Fix It

A 504 Gateway Timeout error means a gateway server did not receive a response from an upstream server within the allowed time. This guide covers every cause — from slow database queries to misconfigured timeouts — and provides targeted fixes.

How a 504 Error Happens

A 504 error follows a specific sequence: a client sends a request to a gateway (Nginx, a CDN, or a load balancer), the gateway forwards it to an upstream server, and the upstream server takes too long to respond. The gateway's timeout expires and it returns 504 to the client.

Root causeWhere it originatesFix
Slow database queryDatabase layerAdd indexes, optimize queries, add caching
Nginx proxy_read_timeout too shortNginx configurationIncrease timeout values
PHP max_execution_time too shortPHP configurationIncrease execution time limit
External API call taking too longApplication codeAdd async processing or increase timeout
Server under heavy loadServer resourcesScale up or optimize resource usage
Network latency between gateway and upstreamNetwork/infrastructureMove services closer or use faster networking

Quick Diagnosis

Terminal — identify the slow component
# Check Nginx error log for timeout messages
sudo grep "upstream timed out" /var/log/nginx/error.log | tail -20

# Check server load
uptime && free -h

# Check slow MySQL queries (if using MySQL)
sudo mysql -e "SHOW PROCESSLIST;" | grep -v Sleep

# Check slow query log (if enabled)
sudo tail -50 /var/log/mysql/mysql-slow.log

Fix: Nginx Timeout Settings

Nginx has several timeout directives that control how long it waits for upstream responses. Increase them to match your application's expected processing time:

/etc/nginx/nginx.conf or site config
http {
    # How long to wait for upstream to accept a connection
    proxy_connect_timeout 60s;
    
    # How long to wait for upstream to send data
    proxy_send_timeout 120s;
    
    # How long to wait for upstream to respond (most important)
    proxy_read_timeout 300s;
    
    # For PHP-FPM via FastCGI:
    fastcgi_connect_timeout 60s;
    fastcgi_send_timeout 120s;
    fastcgi_read_timeout 300s;
}
Terminal — reload Nginx
sudo nginx -t && sudo systemctl reload nginx
Increasing timeouts is a short-term fix. If requests regularly take 300 seconds, the underlying performance problem must be addressed. Very long timeouts also hold server connections open, reducing capacity for other requests.

Fix: Slow Database Queries

Slow database queries are the most common cause of 504 errors in production applications. Enable the slow query log to identify problematic queries:

MySQL — enable slow query log
# In /etc/mysql/mysql.conf.d/mysqld.cnf:
slow_query_log = 1
slow_query_log_file = /var/log/mysql/mysql-slow.log
long_query_time = 2  # Log queries taking > 2 seconds

# Restart MySQL
sudo systemctl restart mysql
MySQL — analyze slow queries
# Use EXPLAIN to see query execution plan
EXPLAIN SELECT * FROM orders WHERE user_id = 123;

# Add an index if missing
ALTER TABLE orders ADD INDEX idx_user_id (user_id);

# Check existing indexes
SHOW INDEX FROM orders;
Adding the right database index can reduce query time from seconds to milliseconds. Use EXPLAIN to identify queries doing full table scans (type: ALL in the output) — these are the best candidates for indexing.

Fix: PHP Execution Time Limit

PHP has a max_execution_time setting that terminates scripts running too long. If this is shorter than Nginx's timeout, PHP will terminate the script before Nginx times out, causing a 504:

/etc/php/8.2/fpm/php.ini
; Increase PHP execution time limit (in seconds, 0 = unlimited)
max_execution_time = 300

; Also increase input time for large uploads
max_input_time = 300
Terminal — restart PHP-FPM
sudo systemctl restart php8.2-fpm

Fix: CDN and Load Balancer Timeouts

If a CDN or load balancer sits in front of your server, it has its own timeout settings that may be shorter than your server's timeouts. Common CDN timeout defaults:

ProviderDefault timeoutHow to increase
Cloudflare (free)100 secondsUpgrade to Pro/Business for longer timeouts
AWS ALB60 secondsModify idle timeout in load balancer settings
AWS CloudFront30 secondsIncrease origin response timeout in distribution settings
Nginx (reverse proxy)ConfigurableSet proxy_read_timeout in nginx.conf

Fix: Application-Level Optimizations

For long-running operations (report generation, bulk imports, external API calls), the best fix is to move the work out of the synchronous request-response cycle:

  • Background job queues: Move long-running tasks to a queue (Redis + Bull, RabbitMQ, AWS SQS). Return a 202 Accepted immediately and poll for results.
  • Database query caching: Cache expensive query results in Redis or Memcached. Serve cached results for repeated identical queries.
  • Pagination: Never load all records at once. Paginate large datasets to keep individual queries fast.
  • Database connection pooling: Use a connection pool to avoid the overhead of creating a new database connection for every request.

Catch 504 Errors and Slow Responses Instantly

Alive24x7 monitors both uptime and response time. Get alerted when your site returns a 504 error or when response times exceed your threshold — before users start complaining.

Start Free Monitoring

Frequently Asked Questions

Related Articles