A 504 means nginx waited for the backend and it didn't answer in time. Unlike a 502 (bad response), a 504 is purely about slowness — a script, a query, or an overloaded backend. Here is how to fix it.
Quick answer
A 504 Gateway Timeout means nginx waited too long for the backend. The cause is slowness: a long PHP script or slow database query, or an overloaded backend. Find and optimise the slow script or query first, add resources if the backend is overloaded, and only then raise fastcgi_read_timeout or proxy_read_timeout.
Cause 1: a slow script or query
The usual cause — a long-running PHP script or a slow database query exceeds the proxy timeout. Find it in the slow log and optimise it (add an index, cache the result, or move heavy work to a background job).
Cause 2: the backend is overloaded
If PHP-FPM has too few workers for the traffic, requests queue and time out. Raise pm.max_children sensibly (watch RAM) so requests aren't waiting in line.
Cause 3: timeout set too low
If the work is legitimately long (an import, a report), raise the timeout — but treat that as a last resort, not a fix for slow code:
# nginx
fastcgi_read_timeout 120s;
proxy_read_timeout 120s;A 504 is a symptom of something slow. Bumping the timeout stops the error but the request is still slow for users. Optimise the script/query first.
504 = too slow. Find the slow script/query and fix it; add FPM workers; only raise timeouts as a last resort.
Cause 4: an external API or remote request hanging
If your code calls an external API (payment gateway, webhook, another service) with no timeout set, a hung remote call blocks the whole request until nginx gives up. Always set a short, explicit timeout on outbound HTTP calls in your code.
Cause 5: DNS or network latency to a dependency
A slow DNS lookup or a network hiccup to your database or cache server can silently add seconds per request. If 504s are intermittent rather than constant, check the network path and latency to any external dependency.
How to prevent 504s
- Add database indexes and cache expensive queries.
- Set explicit timeouts on any outbound API/HTTP call.
- Monitor slow-query and PHP-FPM slow logs proactively, not just after an outage.
- Size pm.max_children to your traffic and RAM.
Related errors
A 504 (too slow) is different from a 502 Bad Gateway (a bad/no response, often a crash). If it's specifically MySQL that's slow or refusing connections, see MySQL too many connections. For a WordPress site that's generally slow, see how to speed up WordPress.