{ }HttpStatus.com

504 Gateway Timeout

A server acting as a gateway or proxy did not receive a timely response from the upstream server it needed to complete the request.

Defined in RFC 9110 §15.6.5

What 504 means

HTTP 504 Gateway Timeout means a server acting as a gateway or proxy, such as nginx, an ALB, or Cloudflare, forwarded the request to an upstream server but did not get a response within the time it was configured to wait. RFC 9110 groups this with 502 as a two-server problem: the proxy is reporting that the next hop in the chain was too slow, not that the request was invalid. The key difference from 502 is timing rather than malformed data; the upstream may eventually have produced a valid response, it simply did not arrive before the proxy gave up waiting and returned an error to the client.

Every proxy layer has its own timeout setting, and a 504 appears whenever the upstream takes longer than the shortest one in the chain. nginx's proxy_read_timeout, which defaults to 60 seconds, controls how long it waits between bytes from the upstream after forwarding a request, and is the single most common nginx setting to tune when legitimate but slow requests are being cut off; Application Load Balancers, API Gateway, and CDNs each impose their own separate ceiling, often lower than what the origin application itself is configured to allow, so raising one timeout without checking the others still leaves the shortest one in charge.

A frequent root cause is a slow database query: a missing index, a lock held by another transaction, or a report-style query scanning a large table can easily take longer than a proxy's default timeout, especially under load when connections queue behind each other. The fix is rarely to simply raise the timeout further, since that just makes users wait longer for the same slow query; profiling and indexing the query, or moving heavy work to a background job, addresses the actual bottleneck instead of masking it with more patience upstream.

Serverless and container platforms add their own version of this problem through cold starts: when a function or container has been idle and needs to be provisioned from scratch, the first request can take several seconds longer to start executing, and if that startup time plus execution time exceeds the gateway's timeout, the caller sees a 504 even though the function would have succeeded given more time. Keeping functions warm, minimizing bundle size and dependency initialization, and setting gateway timeouts with cold-start latency in mind all reduce how often this shows up in production.

Common causes

  • A database query takes too long due to a missing index, table lock, or large unoptimized scan, exceeding the proxy's read timeout.
  • The proxy's timeout, such as nginx's proxy_read_timeout, an ALB idle timeout, or API Gateway's integration timeout, is shorter than the time the upstream legitimately needs.
  • A serverless function or container cold start delays the first byte of the response past the gateway's timeout window.
  • The upstream server is overloaded and queuing requests, so it eventually responds but well after the proxy has already given up.
  • A downstream call the upstream depends on, such as a third-party API or another internal microservice, is itself slow or hanging, and the delay propagates up the chain.
  • A network issue between the proxy and the upstream, such as packet loss, an overloaded NAT gateway, or DNS resolution delay, adds latency the timeout does not account for.

How to fix a 504

If you are the client (browser user or API caller)

  • Retry the request, since a 504 does not necessarily mean the operation failed on the server, only that the response did not arrive in time.
  • For long-running operations, switch to an async pattern, submitting the job and polling a status endpoint or using a webhook, instead of waiting on one long synchronous request.
  • Increase your own client-side timeout only if you have confirmed with the server operator that the operation legitimately needs more time.
  • Avoid retrying non-idempotent requests, such as a payment charge, blindly after a 504, since the original request may have completed on the server even though the response timed out.
  • Report the specific endpoint and typical duration to the API provider, since they may need to raise a specific timeout or optimize a specific query.

If you run the server

  • Profile and index slow database queries rather than only raising the proxy's read timeout, since a longer timeout just delays the same underlying problem.
  • Audit every timeout in the request path, including the proxy read timeout, load balancer idle timeout, API gateway integration timeout, and application framework timeout, and align them so the outermost one is not shorter than what the backend needs.
  • Keep serverless functions warm with scheduled pings or provisioned concurrency, and minimize cold-start time by trimming dependencies and initialization work.
  • Move slow, non-time-critical work, such as report generation, bulk emails, or large exports, to background jobs or queues instead of handling it inline in a synchronous request.
  • Add timeouts and circuit breakers on calls to downstream dependencies so one slow internal service cannot silently propagate delay all the way up to the edge.

Example

# nginx.conf
location /api/ {
    proxy_pass http://app_upstream;
    proxy_read_timeout 60s;   # gives up after 60s of upstream silence
}

# Resulting response when the upstream query runs long:
HTTP/1.1 504 Gateway Timeout
Content-Type: text/html

<html><body><h1>504 Gateway Timeout</h1></body></html>
The default 60-second proxy_read_timeout cuts off a slow report query well before it would have finished.

Try it live

Our free status responder returns a real HTTP 504 you can point tests, monitors or a browser at.

GET https://mcp.httpstatus.com/status/504

Related status codes

Tools for debugging this