HTTP 504 Gateway Timeout (proxy waited too long)
A middleman (proxy, load balancer or CDN) gave up waiting for the real server. The upstream was too slow — not necessarily dead.
What 504 is saying
Status class 5xx = the server side failed. With 504 the failing party is often the edge (nginx, Envoy, AWS ALB, Cloudflare, API gateway) reporting that the origin did not finish within proxy_read_timeout, proxy_connect_timeout, idle timeout or similar.
HTTP/1.1 504 Gateway Timeout
Content-Type: text/html
Connection: keep-alive
<html><body><h1>504 Gateway Time-out</h1>
The server didn't respond in time.</body></html>
504 vs lookalikes
| Code | Means | Typical cause |
|---|---|---|
| 502 Bad Gateway | Upstream reply invalid or connection failed | Crash, wrong port, TLS mismatch, empty reply |
| 503 Service Unavailable | Temporarily unavailable | Maintenance, overload, no healthy targets, draining |
| 504 | Gateway timed out waiting | Slow DB/API, long request, timeout too short |
| 408 Request Timeout | Server timed out waiting for the client | Client stalled sending the body |
| 429 Too Many Requests | Rate limit | You (or your IP) asked too often |
| Cloudflare 524 | Origin connected; no HTTP response in time | Same family as 504 at the CDN edge |
Common causes
- Slow upstream work — N+1 queries, lock waits, cold caches, huge exports, synchronous third-party APIs.
- Proxy timeout shorter than the app — nginx
proxy_read_timeout 60swhile the app legitimately needs 90s. - Pool exhaustion — every worker blocked; new requests sit until the gateway gives up (may also surface as 502/503).
- Wrong upstream — hanging TCP to a black hole host (sometimes 504, sometimes ETIMEDOUT before HTTP).
- WebSocket / long poll — idle timeouts killing long-lived connections (see also WebSocket connection failed).
Diagnose quickly
# Status only
curl -sI https://example.com/slow-path
# Time to first byte vs total
curl -o /dev/null -s -w "connect:%{time_connect} ttfb:%{time_starttransfer} total:%{time_total} code:%{http_code}\n" \
https://example.com/slow-path
# Compare hitting origin bypassing the CDN (if you control DNS / hosts)
If curl to the origin is fast but through the CDN/proxy is 504, raise or align edge timeouts — or make the work async. If origin itself is slow, fix the query/job, not only the timeout number.
Fix checklist
- App — profile the slow route; add indexes, cache, pagination; move long jobs to a queue and return 202.
- Proxy — align
proxy_read_timeout/ ALB idle timeout / Cloudflare “Proxy Read Timeout” with real needs; do not set infinite. - Upstream health — confirm the process is up and accepting (else you may see 502 instead).
- Client retries — retry idempotent GETs with jitter; do not blindly re-POST payments. Prefer 503 +
Retry-Afterfor planned overload. - Observability — correlate 504 timestamps with DB slow-query logs and upstream p99 latency.
nginx sketch
location / {
proxy_pass http://app_upstream;
proxy_connect_timeout 5s;
proxy_send_timeout 60s;
proxy_read_timeout 60s; # raise carefully; fix slow handlers first
}
Related
Cloudflare Error 521 · Cloudflare Error 522 · Cloudflare Error 524 · 502 Bad Gateway · HTTP 503 Service Unavailable · HTTP 429 Too Many Requests · ETIMEDOUT / connect timed out · net::ERR_CONNECTION_TIMED_OUT · ECONNRESET · TypeError: Failed to fetch · Anvil HTTP status · Wirebook: when sites get tired
Questions
What does HTTP 504 Gateway Timeout mean?
A proxy or load balancer waited for the upstream server and gave up. The origin was too slow (or unreachable in time), so the gateway returned 504.
How is 504 different from 502?
502 usually means a bad or missing upstream reply (crash, wrong socket). 504 means the gateway timed out waiting for a reply that never finished in time.
How is 504 different from 503?
503 means the service is unavailable (maintenance, overload, no healthy backends). 504 is specifically a gateway wait timeout.
What is Cloudflare 524?
Cloudflare connected to your origin but did not get an HTTP response before its timeout — same family as 504 at the CDN edge.
How do I fix 504 Gateway Timeout?
Speed up or async the slow upstream work, then align proxy_read_timeout / load-balancer idle timeouts. Raising timeouts alone without fixing the bottleneck just makes users wait longer.
Should clients retry on 504?
For safe GETs, yes with backoff and jitter. Avoid automatic retries on non-idempotent POSTs unless the API is designed for it.
Published .