504 Gateway Timeout — And Why Raising the Timeout Is the Wrong Fix
A 504 Gateway Timeout is a deadline being enforced. A front server passed your request to a backend, waited the configured number of seconds, heard nothing back, and gave up. Crucially, the backend was reachable — it just did not finish in time.
That makes 504 the most informative of the 5xx codes, because it tells you the problem is duration rather than availability. It also makes it the most commonly mis-fixed: the obvious response is to increase the timeout, which converts a page that fails in 30 seconds into a page that fails in 120. This guide covers what really causes 504s and what to do instead.
How 504 Differs from 502
These two arrive from the same place — the front server — and are easy to confuse. The difference is whether the backend answered at all.
| Symptom | 502 Bad Gateway | 504 Gateway Timeout |
|---|---|---|
| What the backend did | Replied with something unusable, or not at all | Was reachable but did not finish in time |
| Typical timing | Fails almost immediately | Fails after a fixed wait — 30 or 60 seconds |
| Usual cause | Process crashed, or was never running | Slow query, slow external API, heavy job |
| Where to look | Is the service alive? Check the system log | What is slow? Check the slow query log and profiling |
| Effect of a restart | Often fixes it immediately | Fixes it briefly, then it returns under load |
What Actually Causes 504s
- A slow database query. Almost always the top cause. A missing index on a table that has grown means a query that took 50 ms last year now takes 40 seconds.
- A slow or unresponsive external API. Your code calls a payment gateway, a shipping quote or a mail service that stops responding, and your page waits for it with no timeout of its own.
- A heavy scheduled job running in the request. Imports, exports, report generation and bulk emails that were fine with a hundred rows and are not fine with a hundred thousand.
- Not enough PHP-FPM workers for the traffic. Requests queue behind each other until the ones at the back exceed the timeout, even though each individual request is reasonably fast.
- An inefficient plugin or a bad loop. A query inside a loop that runs once per row turns a single page load into thousands of round trips.
- A server that is out of resources. When CPU is saturated or the machine is swapping, everything slows down at once and normal requests start exceeding the deadline.
Why Raising the Timeout Does Not Fix It
Increasing the timeout from 60 to 300 seconds does make the error go away, and that is exactly the problem — it hides a symptom that was telling you something true. The visitor now stares at a blank tab for five minutes instead of getting an error in one. Almost nobody waits.
Worse, it makes the underlying failure spread. Every request that is now allowed to run for five minutes holds a worker process for five minutes. With a fixed number of workers, a handful of slow requests can consume all of them, and requests that would have been perfectly fast start queueing behind them. Raising the timeout converts a problem affecting one page into a problem affecting the whole site.
There is one legitimate case: a genuinely long-running operation that a human deliberately triggered and is waiting for, such as a large import in an admin panel. Even then, the right answer is usually to move the work to a background job and show progress, rather than holding an HTTP connection open.
Fixing the Actual Cause
- Find out what is slow before changing anything. Enable the MySQL slow query log, or use a profiler such as Query Monitor on WordPress. Guessing wastes far more time than measuring.
- Add the missing index. When a slow query is the cause, an index on the column being filtered or joined is frequently the entire fix, and can turn 40 seconds into milliseconds.
- Put a timeout on every outbound call your code makes. If an external API is unresponsive, your page should give up after a few seconds and degrade gracefully rather than waiting as long as the gateway allows.
- Move long jobs out of the request. Imports, exports and report generation belong in a queue or a cron task, with the page returning immediately and reporting progress separately.
- Cache the expensive parts. A page rebuilt from scratch on every request will eventually exceed any deadline; a cached one will not.
- Increase the number of PHP-FPM workers if requests are queueing rather than individually slow. This is a real fix when the problem is concurrency, and useless when the problem is one slow query.
- Give the server more resources if it is genuinely saturated. If CPU sits at 100% during normal traffic, no amount of tuning will help — the machine is too small for the workload.
Running out of CPU during peak traffic?
Cloud VPS with dedicated cores and NVMe storage — no noisy neighbours competing for the same resources. From ฿150/month.
Frequently Asked Questions
Why do I only get a 504 on one specific page?
Because that page does something the others do not — a heavy report, a large export, an external API call. Being isolated to one page is good news: it points straight at the code responsible instead of at the server as a whole.
It only happens at peak hours. What does that tell me?
That it is a capacity problem rather than a bug. Individual requests are probably fine; there are just not enough workers or enough CPU to run them all at once, so requests queue and the ones at the back time out. Adding workers helps if you have the memory; otherwise the server needs to be bigger.
Does a 504 affect SEO?
Occasional ones, no — Google retries. Persistent ones, yes: crawl rate drops and pages can be dropped from the index. Google also uses page speed as a ranking signal, so a site producing 504s is almost certainly slow enough to be losing ground before the errors even start.
GUIDES
Related articles
Keep reading on similar topics
502 Bad Gateway — What It Means and How to Fix It
A 502 means one server asked another server for the page and got back something it could not use. This guide explains which two machines are involved, how 502 differs from 500 and 504, and the order to work through the causes so you find the real one first.
Read more503 Service Unavailable — Deliberate or Overloaded?
A 503 is the only 5xx that is often completely intentional. The server is up and healthy and has decided not to serve you right now. Telling a planned maintenance page from a server buckling under load is the first thing to establish, and this guide shows you how.
Read moreERR_CONNECTION_TIMED_OUT — What It Means and How to Fix It
The page just hangs and then Chrome says ERR_CONNECTION_TIMED_OUT. This guide shows you how to work out in two minutes whether the problem is on your side or the server side, then walks through the fixes for each — plus how this error differs from the similar-looking ones people confuse it with.
Read more