How to Fix 504 Gateway Timeout

The origin is too slow, not down. Different problem, different fix.

A 504 means the proxy waited too long for the origin. Fix upstream timeouts, PHP max_execution_time, and load balancer config.

What a 504 means

A 504 Gateway Timeout is returned by a proxy when it forwards a request to an upstream server and the upstream doesn't respond within the proxy's timeout window. The origin is reachable (otherwise you'd get a 502) but too slow. The proxy gives up and returns 504 to the client.

This is fundamentally a timeout problem, not a connectivity problem. The fix is either to make the origin faster, raise the proxy's timeout, or both. Raising the timeout is a bandage — it makes the user wait longer before seeing an error but doesn't fix the underlying slowness. Always investigate the origin first.

Check the origin: PHP max_execution_time and slow queries

On PHP stacks, the most common cause is `max_execution_time` being hit. PHP kills the process at the limit (default 30s), the connection drops, and Nginx returns 504. Check the PHP-FPM log for "Maximum execution time exceeded." If your legitimate requests need more time, raise the limit — but first ask why a request takes 30+ seconds. A slow database query, an external API call without a timeout, or a loop processing too many rows are the usual culprits.

On Node, Python, and Ruby stacks, look for an event-loop block, a synchronous call to a slow service, or a query that's gone quadratic. Add timeouts to every outbound call so one slow dependency can't hang the whole request. The origin logs will show which request path is slow; a 504 that only hits one endpoint points you straight at it.

Check the proxy and load balancer timeouts

If the origin is legitimately slow (a long report generation, a heavy export), raise the proxy timeout so the proxy doesn't give up before the origin finishes. In Nginx, that's `proxy_read_timeout` and `proxy_connect_timeout`. In Apache, `ProxyTimeout`. In AWS ALB, the idle timeout (default 60s). In Cloudflare, the origin response timeout (100s on free plans). Set every layer in the chain to the same value or the shortest one wins.

Check the load balancer health checks too — if the LB marks an instance unhealthy because its health check times out, it stops sending traffic, and the remaining instances get overloaded, causing more 504s. A timeout cascade is common: one slow instance fails its health check, load shifts, the rest slow down, more fail. SurePing's HTTP monitoring with response-time tracking catches the latency creep before it becomes a 504 storm.

Related