504 Gateway Timeout
A gateway timed out waiting for a response from an upstream server.
What 504 means
504 means the proxy gave up waiting. The upstream was reachable - it accepted the connection - but did not produce a complete response within the proxy's timeout. That distinguishes it from 502, where the response was unusable or the connection died.
The critical thing to understand is that the request is very often still running. The proxy has stopped waiting and returned an error to the client, but the upstream may well finish the work seconds later - which makes a naive retry dangerous. Retrying a non-idempotent operation that timed out can duplicate it, and this is a real source of double charges and duplicate records.
Timeouts also compound through a chain. If a CDN allows 30 seconds, a load balancer 60 and the application 120, the client sees a 504 from the CDN while the application is still working. Timeouts should decrease as you move outward, and each layer should be aware of the budget it has left.
Common causes are slow database queries with no index, a downstream call with no timeout of its own, and a request doing work that should have been a background job.
Common causes of a 504
- A slow database query - usually a missing index or stale statistics.
- A downstream API call with no timeout, so the request waits indefinitely.
- Synchronous work that should be a background job: report generation, bulk import, image processing.
- A misconfigured timeout chain where an outer layer is stricter than an inner one.
- Connection pool exhaustion causing requests to queue.
- A lock contention or deadlock stalling the request.
- A cold start on a serverless platform exceeding the gateway's timeout.
How to fix a 504
- Find the slow operation with EXPLAIN ANALYZE or a request trace - the cause is almost always one identifiable step.
- Set explicit timeouts on every outbound call; an unbounded call is how one slow dependency stalls everything.
- Make timeouts decrease outward, so an inner layer gives up before the outer one does.
- Move long-running work to a background job and return 202 with a status URL.
- Use idempotency keys so a client retry after a 504 cannot duplicate the operation.
Should a client retry?
Dangerous to retry blindly - the original request may still be running and may yet succeed. Safe for idempotent operations; for anything else use an idempotency key first.
FAQ
- What is the difference between 502 and 504?
- 504 means the upstream was reachable but too slow - the gateway gave up waiting. 502 means it responded with something unusable, or the connection failed or closed mid-response.
- Is it safe to retry after a 504?
- Not blindly. The original request may still be running and may complete after you retry, duplicating the effect. Safe for idempotent operations; for anything that creates or charges, use an idempotency key.
- How should timeouts be configured across layers?
- Decreasing outward: the application's own timeout should be shorter than the load balancer's, which should be shorter than the CDN's. Otherwise the client gets a 504 while the work is still in progress inside.
- What if the work legitimately takes minutes?
- Then it should not be a synchronous request. Accept it with 202, return a status URL the client can poll, and do the work in a background job.
Often confused with
- 502 Bad Gateway A server acting as a gateway received an invalid response from an upstream server.
- 503 Service Unavailable The server is temporarily unable to handle the request - overloaded or down for maintenance.