Guide Errors & Troubleshooting

How to fix a 504 Gateway Timeout

Something upstream took too long to answer and the gateway gave up waiting — here is how to find exactly what was slow.

Updated 7 min read Intermediate

A 504 Gateway Timeout means a server acting as a gateway or proxy sent your request onward and gave up waiting for a reply before one arrived. The distinction from a 502 matters: a 502 is a bad or missing response, a 504 is no response in time. Something behind the gateway was still working when the clock ran out.

That "something" is almost always a single slow operation — a script, a database query, or a call out to another service — rather than the whole site being generally slow. Finding which specific operation is the point of everything below.

The causes, in the order worth checking

1. A single script is genuinely taking too long

Large imports, exports, backups, and bulk operations run through a normal web request often exceed the time a gateway is willing to wait, even when the script would eventually finish successfully. This is less a bug than a mismatch: web requests are meant to be short, and a job that takes minutes doesn't belong in one.

If the 504 correlates with a specific action — starting an import, generating a large report, running a bulk update — that action is your cause, and the fix is to move it out of the request/response cycle entirely: run it from the command line where no such timeout applies, or as a background/cron job that reports back when finished rather than making the browser wait.

2. A database query is slow

An unindexed table, a query against a large dataset, or a lock held by another process can turn what should be an instant lookup into a multi-second wait, and enough of those stacked in sequence on one page load is enough to trigger a timeout. The error log won't usually show this directly, but slow-query logging — available in most database tools — will name the exact query responsible if it's enabled.

3. The site is waiting on a slow or unresponsive third-party service

A page that calls out to a payment gateway, a shipping calculator, a social media API, or any other remote service is only as fast as that service's own response time. If the third party is degraded or unreachable, and the code calling it has no timeout of its own, the request can hang until the gateway's limit is reached rather than failing quickly with a useful error. Check whether the affected pages share a common external dependency before assuming the problem is local.

4. The gateway or proxy timeout is set too low for a legitimate operation

Some operations are simply going to take longer than a default timeout allows, even running efficiently — a genuinely large data export, for instance. Where that's the case, the timeout itself can be raised in your control panel's PHP settings (max_execution_time) alongside any equivalent limit on a CDN or proxy sitting in front of the site. Treat this as appropriate for known long-running, legitimate operations, not as a blanket fix for a slow site in general — it doesn't make a slow query faster, it just waits longer for the same result.

5. The server itself is under heavy load

Under sufficient load, even ordinarily fast operations can queue up behind each other and collectively exceed a gateway timeout. This shows up alongside other symptoms of resource pressure — general sluggishness across the whole site, not just one page — which is the distinguishing sign that points here rather than at a single specific script.

Time the request directly

Run curl -o /dev/null -s -w '%{time_total}\n' https://yourdomain.com/the-slow-page from a terminal to see exactly how long a request takes before it fails. Comparing that figure against the configured timeout confirms whether you're dealing with a request that's merely slow or one that would never finish at all.

Turning on slow-query logging temporarily

If a database query is suspected but not confirmed, most database management tools offer a slow-query log that records any query over a chosen threshold along with how long it took. Turn it on, reproduce the 504, then turn it back off — leaving it running permanently adds overhead of its own and isn't necessary once you have the answer.

If you can't isolate it

The most useful things to send along are the exact URL that times out, roughly how long it takes to fail, and whether it involves any external service, import, or large dataset. With that, support can check server-side timing directly rather than guessing between a slow query, a slow script, and a slow third party.

Frequently asked questions

Is a 504 the same as a 502?

No. A 502 means the gateway got a response and it was invalid, or the upstream connection was refused outright. A 504 means the gateway got no response in time at all — it was waiting on something that was still running when the timeout expired. Broken versus slow is the distinction.

Why does the same page work sometimes and time out other times?

Because whatever is slow is usually data-dependent or load-dependent rather than permanently broken — a database query that is fast on a small dataset and slow on a large one, or an external API that responds quickly except under its own load. Consistent timeouts point at something structurally slow; intermittent ones point at something that is only occasionally slow.

Related reading