504
Gateway Timeout
5xx Server Error

What Does HTTP 504 Gateway Timeout Mean?

HTTP 504 Gateway Timeout means a server acting as a gateway or proxy did not receive a timely response from the upstream server it needed to complete the request. The proxy waited for a response, the timeout expired, and it gave up.

This is different from a regular timeout (where the browser times out waiting for the server). With 504, the client's request reached the proxy server successfully, but the proxy could not get the backend to respond in time. The bottleneck is between the proxy and the upstream server, not between the client and the proxy.

Every layer in the request chain has its own timeout: CDN (e.g., Cloudflare: 100s), load balancer (e.g., AWS ALB: 60s), reverse proxy (e.g., Nginx: 60s). A 504 occurs when the shortest timeout in the chain expires before the backend responds.

Common Causes

How to Fix It

Quick Fix: Increase Timeout (Symptom, Not Cure)

# Nginx - Increase proxy timeouts location /api/ { proxy_pass http://backend; proxy_connect_timeout 10s; # Time to establish connection proxy_send_timeout 60s; # Time to send request to upstream proxy_read_timeout 120s; # Time to wait for response (increase this) } # AWS ALB - Increase idle timeout (via Console or CLI) aws elbv2 modify-load-balancer-attributes \ --load-balancer-arn arn:aws:... \ --attributes Key=idle_timeout.timeout_seconds,Value=120 # Cloudflare - Enterprise plan allows custom origin timeouts # Free/Pro plans: fixed at 100 seconds

Real Fix: Optimize the Slow Backend

# Find slow queries (MySQL) # Enable slow query log SET GLOBAL slow_query_log = 'ON'; SET GLOBAL long_query_time = 2; -- Log queries over 2 seconds # Check the slow query log mysqldumpslow /var/log/mysql/slow-query.log # Add missing indexes EXPLAIN SELECT * FROM orders WHERE user_id = 42; -- If you see "type: ALL" (full table scan), add an index: ALTER TABLE orders ADD INDEX idx_user_id (user_id);

Move to Background Processing

// BEFORE: Synchronous (causes 504 on large reports) app.get('/api/report', async (req, res) => { const data = await generateHugeReport(req.query); // Takes 5 minutes res.json(data); // Timeout before this runs }); // AFTER: Async with polling app.post('/api/report', async (req, res) => { const jobId = await queue.add('generate-report', req.query); res.status(202).json({ job_id: jobId, status_url: `/api/report/status/${jobId}` }); }); app.get('/api/report/status/:id', async (req, res) => { const job = await queue.getJob(req.params.id); if (job.isCompleted()) { res.json({ status: 'complete', download_url: job.result }); } else { res.json({ status: 'processing', progress: job.progress }); } });

Add Caching to Prevent Repeated Slow Queries

const redis = require('redis').createClient(); app.get('/api/dashboard', async (req, res) => { const cacheKey = `dashboard:${req.user.id}`; // Try cache first const cached = await redis.get(cacheKey); if (cached) return res.json(JSON.parse(cached)); // Slow query only runs once per cache period const data = await slowDashboardQuery(req.user.id); await redis.setEx(cacheKey, 300, JSON.stringify(data)); // Cache 5 min res.json(data); });

Debugging Timeout Chains

When you see a 504, you need to identify which layer timed out. Check timeouts from outside in:

Frequently Asked Questions

What causes a 504 Gateway Timeout?
A 504 occurs when a proxy or gateway does not receive a response from the backend server within its configured timeout. The most common causes: slow database queries (missing indexes, large result sets), long-running synchronous operations (report generation, bulk processing), upstream server deadlocks, DNS resolution issues, or network problems between the proxy and backend.
How do I fix a 504 Gateway Timeout?
Start by identifying the bottleneck: check Nginx/proxy error logs, enable slow query logging in your database, add timing to your application logs. Quick fix: increase proxy_read_timeout in Nginx. Real fix: optimize slow queries (add indexes), move long-running tasks to background jobs, add caching layers, and implement pagination for large data sets.
What is the difference between 502 and 504 errors?
502 = bad response. The proxy connected to the upstream but got an invalid, incomplete, or refused response (usually a crash). 504 = no response. The proxy waited but the upstream never responded within the timeout. 502 suggests the backend is broken or down. 504 suggests the backend is too slow or stuck.

Related Status Codes

Related Tools