Developer Toolbox
5xx server errorRetry with careComes from the proxy

504 Gateway Timeout

A gateway or proxy forwarded the request but got no response from the server behind it within its time limit. The application may still be working on the request, and may even finish it.

Open cURL Builder Build a verbose request to see where the time goes.

Common causes

  • A slow request: a heavy database query, a report, an export, a call to a slow third-party API.
  • The proxy gives up sooner than the app: nginx's proxy_read_timeout defaults to 60 seconds, and AWS API Gateway gives an integration 29 seconds by default.
  • The app is stuck: every worker busy, a deadlock, an exhausted connection pool.
  • The network between the proxy and the app drops packets, for example a firewall rule, which looks the same as a timeout.

How to fix it

  • Find which layer timed out: the body and the Server header usually name it (nginx, awselb, your CDN). Cloudflare uses its own code, 524, when the origin is too slow.
  • Make slow work asynchronous: accept the request with 202, do the work in a background job, and let the client poll or receive a webhook.
  • Raising the timeout doesn't make the request faster. If you do raise it, set the proxy's limit a little above the app's own, so the app fails cleanly first.
  • Don't blindly retry a POST after a 504: the server may have completed it. Use idempotency keys for anything that creates or charges.

504 or 408?

408 Request Timeout means the client was too slow to send its request. 504 means the server side was too slow to answer it.

504 or 502?

Both come from the proxy. 504 means no answer in time, 502 means a broken answer or a refused connection.

Example

HTTP/1.1 504 Gateway Time-out
Server: nginx
Content-Type: text/html

<html>
<head><title>504 Gateway Time-out</title></head>
<body>
<center><h1>504 Gateway Time-out</h1></center>
<hr><center>nginx</center>
</body>
</html>

Defined in RFC 9110, section 15.6.5.