Error Medic

504 Gateway Timeout Error: Complete Troubleshooting Guide for Web Developers

Fix 504 Gateway Timeout errors in Nginx, AWS, Cloudflare & more. Step-by-step diagnosis and solutions for developers.

Last updated:
Last verified:
1,543 words
Key Takeaways
  • 504 Gateway Timeout occurs when an upstream server fails to respond within the configured timeout period
  • Most common causes are slow database queries, insufficient server resources, or misconfigured proxy timeout settings
  • Quick fixes include increasing timeout values, optimizing backend performance, and implementing proper health checks
504 Gateway Timeout Fix Approaches Compared
MethodWhen to UseTime to FixRisk Level
Increase Timeout ValuesTemporary slow responses5-15 minutesLow
Optimize Database QueriesSlow backend processing1-4 hoursMedium
Scale Server ResourcesResource exhaustion15-30 minutesLow
Implement Load BalancingHigh traffic scenarios2-6 hoursMedium
Fix Application CodeInefficient algorithms4-24 hoursHigh

Understanding the 504 Gateway Timeout Error

A 504 Gateway Timeout error occurs when a server acting as a gateway or proxy does not receive a timely response from an upstream server. Unlike a 502 Bad Gateway error which indicates connection failure, the 504 error specifically means the connection was established but the upstream server took too long to respond.

Common Scenarios Where 504 Errors Occur

Web Server Configurations:

  • Nginx acting as a reverse proxy to PHP-FPM or application servers
  • Apache with mod_proxy forwarding requests to backend services
  • Load balancers (AWS ALB, Azure Application Gateway) timing out on slow backends

Cloud Platforms:

  • AWS API Gateway timing out on Lambda functions (29-second limit)
  • Cloudflare timing out on slow origin servers (100-second limit for free plans)
  • Azure Application Gateway v2 with backend pool response delays

Application Stacks:

  • WordPress sites with slow database queries or heavy plugins
  • Node.js applications with blocking operations
  • PHP applications with long-running scripts

Step 1: Identify the Timeout Source

First, determine which component in your stack is timing out. Check server logs in this order:

  1. Frontend proxy logs (Nginx, Apache, load balancer)
  2. Application server logs (PHP-FPM, Node.js, Python)
  3. Database logs (MySQL slow query log, PostgreSQL)
  4. External service logs (CDN, API gateways)

Step 2: Nginx 504 Gateway Timeout Diagnosis

For Nginx-based setups, check these configuration areas:

Common Nginx timeout directives:

  • proxy_read_timeout - Time to read response from proxied server
  • proxy_connect_timeout - Time to establish connection to proxied server
  • fastcgi_read_timeout - Time to read FastCGI response
  • uwsgi_read_timeout - Time to read uWSGI response

Check current Nginx configuration:

nginx -T | grep -i timeout

Examine Nginx error logs:

tail -f /var/log/nginx/error.log | grep "upstream timed out"

Step 3: AWS-Specific 504 Troubleshooting

AWS API Gateway 504 Errors: API Gateway has a hard 29-second timeout limit. If your Lambda function or backend takes longer, you'll get a 504 error.

Check CloudWatch logs:

aws logs filter-log-events --log-group-name /aws/apigateway/your-api-name --filter-pattern "504"

AWS Application Load Balancer 504 Errors: ALB will return 504 if target instances don't respond within the configured timeout (1-4000 seconds).

Check ALB access logs:

aws s3 cp s3://your-alb-logs-bucket/AWSLogs/account/elasticloadbalancing/ . --recursive
grep "504" *.log

Step 4: Application-Level Optimization

PHP Applications: Increase PHP execution time limits and optimize slow operations:

ini_set('max_execution_time', 300);
ini_set('memory_limit', '512M');

WordPress-Specific Fixes:

  • Deactivate plugins one by one to identify culprits
  • Enable WordPress debugging to identify slow queries
  • Implement object caching (Redis, Memcached)

Node.js Applications: Avoid blocking the event loop with synchronous operations:

// Bad: Synchronous file operation
const data = fs.readFileSync('large-file.txt');

// Good: Asynchronous operation
fs.readFile('large-file.txt', (err, data) => {
  // Handle response
});

Step 5: Database Query Optimization

Identify slow queries in MySQL:

SET GLOBAL slow_query_log = 'ON';
SET GLOBAL long_query_time = 2;
SHOW VARIABLES LIKE 'slow_query_log_file';

PostgreSQL slow query analysis:

SELECT query, mean_time, calls 
FROM pg_stat_statements 
ORDER BY mean_time DESC 
LIMIT 10;

Step 6: Server Resource Monitoring

Check CPU and memory usage:

# Real-time monitoring
top -p $(pgrep -f "nginx|php-fpm|httpd")

# Historical analysis
sar -u 1 60  # CPU usage over 60 seconds
sar -r 1 60  # Memory usage

Monitor disk I/O:

iotop -o  # Show only processes with I/O activity
iostat -x 1  # Extended disk statistics

Step 7: Implement Proper Timeout Configuration

Nginx configuration example:

server {
    location / {
        proxy_pass http://backend;
        proxy_read_timeout 300s;
        proxy_connect_timeout 60s;
        proxy_send_timeout 60s;
    }
    
    location ~ \.php$ {
        fastcgi_pass php-fpm;
        fastcgi_read_timeout 300s;
        fastcgi_send_timeout 60s;
    }
}

Apache configuration example:

<VirtualHost *:80>
    ProxyPass / http://backend/
    ProxyPassReverse / http://backend/
    ProxyTimeout 300
</VirtualHost>

Step 8: Implement Health Checks and Circuit Breakers

Application-level health check:

app.get('/health', (req, res) => {
    // Check database connectivity
    db.ping((err) => {
        if (err) {
            return res.status(503).json({ status: 'unhealthy' });
        }
        res.json({ status: 'healthy' });
    });
});

Step 9: Advanced Monitoring and Alerting

Set up monitoring with Prometheus:

# prometheus.yml
scrape_configs:
  - job_name: 'nginx'
    static_configs:
      - targets: ['localhost:9113']
    scrape_interval: 15s

CloudWatch custom metrics for AWS:

aws cloudwatch put-metric-data \
  --namespace "Custom/Application" \
  --metric-data MetricName=ResponseTime,Value=5.2,Unit=Seconds

Prevention Strategies

  1. Implement caching layers (Redis, Memcached, CDN)
  2. Use connection pooling for database connections
  3. Set up proper monitoring and alerting
  4. Implement graceful degradation for slow services
  5. Use asynchronous processing for heavy operations
  6. Regular performance testing under load conditions

Platform-Specific Solutions

Cloudflare 504 Errors:

  • Check origin server health
  • Verify DNS resolution
  • Review Cloudflare timeout settings in dashboard

Docker/Kubernetes 504 Errors:

  • Check container resource limits
  • Verify service discovery configuration
  • Review ingress controller timeout settings

Magento 2 504 Errors:

  • Increase PHP memory limit and execution time
  • Enable Magento caching
  • Optimize database indexes
  • Use Varnish or Redis for full-page caching

Frequently Asked Questions

bash
#!/bin/bash
# 504 Gateway Timeout Diagnostic Script

echo "=== 504 Gateway Timeout Diagnostics ==="
echo "Timestamp: $(date)"
echo

# Check current connections and server load
echo "Current server load:"
uptime
echo

# Check memory usage
echo "Memory usage:"
free -h
echo

# Check disk space
echo "Disk usage:"
df -h
echo

# Check active connections to web server
echo "Active connections to port 80/443:"
ss -tuln | grep -E ':80|:443'
echo

# Check for high CPU processes
echo "Top 10 CPU consuming processes:"
ps aux --sort=-%cpu | head -11
echo

# Nginx specific checks
if command -v nginx &> /dev/null; then
    echo "Nginx status:"
    systemctl status nginx --no-pager -l
    echo
    
    echo "Recent Nginx errors (last 50 lines):"
    tail -50 /var/log/nginx/error.log | grep -i "timeout\|upstream"
    echo
fi

# Apache specific checks  
if command -v apache2 &> /dev/null; then
    echo "Apache status:"
    systemctl status apache2 --no-pager -l
    echo
fi

# PHP-FPM specific checks
if command -v php-fpm &> /dev/null; then
    echo "PHP-FPM status:"
    systemctl status php*-fpm --no-pager -l
    echo
    
    echo "PHP-FPM pool status:"
    curl -s localhost/fpm-status || echo "FPM status page not configured"
    echo
fi

# Database connection check
echo "Testing database connectivity:"
if command -v mysql &> /dev/null; then
    mysql -e "SELECT 1;" 2>/dev/null && echo "MySQL: Connected" || echo "MySQL: Connection failed"
fi

if command -v psql &> /dev/null; then
    psql -c "SELECT 1;" 2>/dev/null && echo "PostgreSQL: Connected" || echo "PostgreSQL: Connection failed"
fi
echo

# Check for slow queries (if MySQL slow log is enabled)
if [ -f /var/log/mysql/mysql-slow.log ]; then
    echo "Recent slow queries (last 10):"
    tail -50 /var/log/mysql/mysql-slow.log | grep -E "Query_time|User@Host" | tail -20
fi

echo "=== Diagnostic Complete ==="
echo "Next steps:"
echo "1. Review timeout configurations in web server"
echo "2. Check application logs for slow operations"
echo "3. Monitor resource usage during peak times"
echo "4. Consider implementing caching if not present"
E

Error Medic Editorial

Our team of senior DevOps engineers and SREs brings decades of production experience troubleshooting complex web applications across cloud platforms.

Sources

Related Articles in Other 504 Gateway Timeout

Explore More browser Guides