Troubleshooting
504 Gateway Timeout: what causes it and how to fix it
A 504 Gateway Timeout means a proxy gave up waiting for the server behind it. Where timeouts live in nginx, Apache, PHP and CDNs, and how to fix the cause.
Updated · 5 min read
What 504 Gateway Timeout means
A 504 Gateway Timeout means a server acting as a gateway or proxy waited for a response from the server behind it and gave up when its time limit ran out. The request reached the website, but something deeper in the stack was too slow, or never answered.
Most sites run as a chain: a CDN or load balancer, then a web server such as nginx or Apache, then an application server such as PHP-FPM or a Node.js process, and often a database behind that. Each hand-off has its own timeout. A 504 means one of them expired, so the fix starts with finding which one.
504 vs 502 vs Cloudflare's 524
A 502 Bad Gateway means the proxy got a broken response or a refused connection: the backend was down or misbehaving. A 504 means the backend was reachable, or at least not refusing, but did not answer in time. One is usually a crash or misconfiguration, the other usually slowness.
Cloudflare uses its own code for the slow-origin case. Its 524 error means Cloudflare connected to your server but did not receive an HTTP response within its proxy read timeout, which Cloudflare's documentation sets at 125 seconds by default; Enterprise plans can raise it to 6,000 seconds. A 504 seen behind Cloudflare usually comes from a timeout inside your own stack, passed through.
Where the timeouts live
Knowing each layer's default helps you match the time it took to fail with the layer that gave up:
- nginx: proxy_read_timeout and fastcgi_read_timeout default to 60 seconds. nginx logs "upstream timed out (110: Connection timed out)" when one expires.
- Apache: ProxyTimeout applies to proxied requests and defaults to the main Timeout setting, which is 60 seconds by default.
- PHP: max_execution_time limits script run time (30 seconds in the default php.ini), and PHP-FPM's request_terminate_timeout can kill a worker that runs too long.
- Load balancers: many have an idle timeout, for example 60 seconds by default on AWS Application Load Balancers, after which they return 504.
- CDNs: Cloudflare waits 125 seconds by default before returning 524.
Align the timeouts
The timeouts work well nested, with each inner layer giving up before the layer outside it. If PHP stops a script before nginx stops waiting, and nginx stops before the load balancer or CDN does, the failure is reported by the layer closest to the problem, with a clear entry in its log. When the order is reversed, an outer layer returns a generic 504 while the application keeps working on a request nobody is waiting for, using up a worker for nothing.
Connection timeouts are separate from read timeouts. nginx's proxy_connect_timeout, for example, covers only establishing the connection to the backend. A 504 that happens on connecting points at a backend that is unreachable or dropping traffic, not at a slow page.
Common causes
Raising a timeout rarely fixes a 504 on its own. The question is why the response took so long. The usual reasons:
- Slow database queries, such as a missing index, a huge table scan, or a query waiting on a lock held by another process.
- Calls to external services. An API, payment gateway or license server that hangs makes your page hang with it.
- Long jobs run inside a web request: imports, exports, report generation, image processing or backups started from an admin screen.
- An overloaded server. When every worker is busy, new requests queue, and the wait in the queue alone can exceed the timeout.
- A network path that silently drops traffic between the proxy and the backend, for example a firewall rule that drops packets rather than rejecting them, so the connection attempt hangs until it times out.
How to fix a 504 as the site owner
Find the slow layer first, then fix the slow work, and only then consider timeouts:
- 1Confirm from outside with the uptime check. It names the failing stage, so you can see whether the request timed out completely or returned a 504 from a proxy.
- 2Note how long the failing request takes. A failure at about 60 seconds points at a 60-second timeout such as nginx's default; 125 seconds behind Cloudflare points at Cloudflare's limit.
- 3Use the HTTP header checker on a working page of the site to see which layers sit in front (CDN, load balancer, web server), then read each layer's error log at the time of the failure.
- 4Find the slow request. Enable PHP-FPM's slow log or your application's request logging, and the database's slow query log, then reproduce the failing page.
- 5Fix the slow work: add the missing index, put a short timeout and caching on external API calls, and move long jobs out of the web request into a background queue or scheduled task.
- 6If a legitimately long request must stay, such as an admin export, raise the timeouts for that path only, and keep them aligned: an inner timeout longer than the outer one never gets a chance to apply.
- 7If the server is constantly saturated, reduce the load with caching or add capacity.
504 errors on WordPress
On WordPress, 504s cluster around a few patterns: admin pages and admin-ajax requests from plugins that do heavy work, imports and bulk edits, backup or migration plugins running inside a web request, and plugins that call external services on page load. The Query Monitor plugin shows slow database queries and HTTP API calls per request, which points at the responsible plugin.
WP-Cron is another source. By default WordPress runs scheduled tasks on visitor page loads, so a heavy scheduled job can slow random visitor requests. Setting DISABLE_WP_CRON in wp-config.php and running wp-cron.php from a real system cron moves that work off visitor requests.
What visitors can do
A 504 is a problem on the website's side. Reloading after a short wait is worth trying, because a temporary spike or a single slow request may have caused it. If the error appeared after submitting a form or placing an order, check for a confirmation email before resubmitting, since the action may have completed even though the page timed out.
Common questions
- Is a 504 Gateway Timeout caused by the visitor's internet?
- No. A 504 is returned by a server on the website's side when a server behind it is too slow to answer. A slow home connection produces browser timeout errors, not a 504 page.
- How to fix 504 Gateway Timeout in nginx?
- Read nginx's error log for "upstream timed out", then find why the application is slow, such as a slow query or a hanging external call. Raise proxy_read_timeout or fastcgi_read_timeout only for requests that genuinely need longer.
- What is the difference between Cloudflare error 524 and 504?
- A 524 is Cloudflare's own code for an origin that accepted the connection but did not respond within Cloudflare's timeout, 125 seconds by default. A 504 behind Cloudflare usually comes from a timeout inside the origin's own stack.
- Should the timeout just be increased to fix a 504?
- Only as a stopgap or for specific long-running paths. A longer timeout makes visitors wait longer and ties up server workers, while the underlying slow query or call stays slow.
Is my website down?
Down for everyone or just you? Names the exact stage that failed.
Check if your site is downRelated guides
- Why is my website down? How to find the cause, step by stepFind out why your website is down: check if it's down for everyone, decode the error, and test the domain, DNS, SSL and server in the order that saves time.
- 502 Bad Gateway: what it means and how to fix itA 502 Bad Gateway means a proxy got an invalid response from the server behind it. How to find which layer failed, read the logs, and fix the usual causes.
- 503 Service Unavailable: causes and how to fix itA 503 Service Unavailable error means the server is up but can't handle requests right now. The usual causes, WordPress specifics, and what 503s mean for SEO.
- How to fix a slow TTFB: server-side fixes that actually workSlow Time to First Byte is a server or network problem, not a page problem. Find the slow phase, then fix it with caching, a CDN, database work or hosting.