Ana içeriğe geç

Guides / http-status-codes

504 Gateway Timeout: Slow Backends, Timeouts and 502 vs 503 vs 504

A 504 Gateway Timeout means a proxy reached your backend, waited for a response, and gave up before one arrived. Nothing crashed and nothing refused the request: something behind the proxy is slower than the proxy is willing to wait.

What a 504 reports

RFC 9110 defines 504 for a server acting as a gateway or proxy that did not receive a timely response from an upstream server it needed to access. The word "timely" is defined by configuration, not by the specification, so a 504 is always a statement about two things at once: how slow the backend was, and what limit the proxy was set to.

That has an important practical consequence. When a proxy returns 504, the backend usually keeps working on the request. The connection to the client is gone, but the slow query is still running, the report is still being generated, and the resources are still held. This is why a wave of 504s often makes a server worse: every abandoned request leaves work behind, and the queue grows faster than it drains.

504 versus 502 versus 503

502 Bad Gateway503 Service Unavailable504 Gateway Timeout
What happenedBackend gave an invalid response or closed the connectionServer declined the work on purposeBackend accepted the work and never answered in time
Backend stateDown, crashing, or speaking the wrong protocolUp, but overloaded or in maintenanceUp and busy, still processing
Response speedUsually immediateUsually immediateSlow, arrives at the timeout limit
Typical log lineconnect() failed or upstream prematurely closed connectionMaintenance rule, or no healthy upstreamsupstream timed out (110: Connection timed out)
Retry-AfterNot usualCommon and recommendedNot usual
First place to lookIs the backend process running?Capacity, maintenance flags, health checksSlow queries and slow dependencies

In practice a 502 fails fast, a 503 refuses politely, and a 504 makes you wait first. The dedicated 502 guide and the 5xx overview cover the other two in full.

Why the backend is too slow

  • Slow database queries. A missing index, a query that grew with the data, an N+1 pattern in a loop, or lock contention under concurrency. The single most common cause.
  • Slow third-party calls. An outbound API request without a timeout of its own inherits the remote service's worst day and passes it to your visitors.
  • Cold starts. The first request after a scale-up, a container start or an idle period pays for initialization, connection setup and cache warming all at once.
  • Genuinely heavy work on a web request. Report generation, exports, image processing or bulk imports handled synchronously will eventually exceed any reasonable timeout.
  • Resource contention. CPU saturation, memory pressure and swapping make every request slower, so the slowest ones cross the limit first.
  • Timeouts set too tight. If an endpoint legitimately needs longer than the proxy allows, the configuration is the bug rather than the code.
  • Network problems between hops. Packet loss or DNS resolution delays for the upstream address add latency that does not appear in application timings.

How to diagnose and fix a 504

  1. Measure the time to the error. The delay before a 504 usually matches the configured timeout, which tells you which hop produced it:
    curl -sS -o /dev/null -w "%{http_code} %{time_total}s\n" https://example.com/slow-page
    A 504 at almost exactly 60 seconds points at a default proxy read timeout. One at 30 or 100 seconds points at whichever component is configured with that number, often a CDN rather than your own proxy.
  2. Find whether it is one endpoint or all of them. One slow URL is an application problem. Everything slow at once is resource saturation or a failing dependency.
  3. Read the proxy error log. With nginx the line is explicit:
    [error] upstream timed out (110: Connection timed out) while reading
            response header from upstream, upstream: "http://127.0.0.1:8080/"
    It names the upstream and the phase, which separates a slow connect from a slow response.
  4. Time the backend directly, without the proxy. If the same request takes 90 seconds against the origin, the proxy is reporting the truth and the fix belongs in the application.
  5. Profile the slow path. Check the slow query log, then application traces. Most 504s resolve to one query or one outbound call.
  6. Fix the cause before the timeout. Add the index, cache the expensive result, or move genuinely long work to a background job that returns immediately and reports progress separately.
  7. Raise the timeout only when the work is legitimately long, and raise it consistently on every hop. A CDN limit of 30 seconds makes a 120-second origin timeout pointless.
  8. Set timeouts on your own outbound calls so a slow dependency fails fast with a clear error instead of consuming a worker until the proxy gives up.

Response time is the early warning

A 504 is the end state of a slowdown that was building for a while. Response times drift from half a second to two seconds to ten, and nobody notices until requests start crossing the limit. A scheduled HTTP check records the response time of every check alongside the status code, so the trend is visible as a graph long before the first timeout, and the alert arrives on the first real failure rather than after the support queue fills. Checking from several regions helps as well, because a route that is fast from one continent and slow from another points at the network path or edge configuration rather than at your database.

Check it now

Run the free check against your own site - no account needed.

HTTP check

Monitor this permanently

Get alerted the moment it breaks: HostTracker checks from 300+ locations and notifies you by email, SMS, Slack, Telegram and more.

HostTracker features