Halloween offer: 50 % off your first year Ends in 27d 14h 42m Start free trial

Guides 6 min read

504 Gateway Timeout: What It Means and How to Fix It

A 504 Gateway Timeout means a proxy waited for the server behind it and gave up. How to find the slow part, fix it instead of just raising timeouts, and see slowdowns before they turn into 504s.

A 504 Gateway Timeout error means a server acting as a gateway or proxy waited for an answer from the server behind it and gave up. The request reached your CDN, load balancer or web server, was passed on to the application, and the application did not respond before the time limit ran out.

The server behind the proxy is often still running. It’s just too slow, or something it waits for is. That makes a 504 different from most outages: restarting things rarely fixes it for long. This guide shows how to find which timeout fired, what usually makes the request slow and how to fix the cause rather than the symptom.

What a 504 tells you

A request to a modern website passes through several layers, and each one has its own limit on how long it waits for the next:

  • A CDN such as Cloudflare waits a fixed time for your origin.
  • A load balancer has an idle or response timeout per target.
  • nginx waits for the upstream according to proxy_read_timeout or fastcgi_read_timeout, 60 seconds by default.
  • The application has its own limits, like PHP’s max_execution_time or a worker timeout in Gunicorn.

The 504 comes from the first layer whose limit runs out. Its neighbours mean something else: a 502 Bad Gateway means the upstream answered with something invalid or not at all, and a 503 Service Unavailable means the service refused the request because it is overloaded or in maintenance.

Find the timeout that fired

Time the request. A 504 that always arrives after the same number of seconds points at one specific limit:

curl -s -o /dev/null -w "status %{http_code} after %{time_total}s\n" https://www.example.com/reports
status 504 after 60.04s

Then look at the response headers and the error page to see which layer answered, as with any 5xx error. A plain nginx page with server: nginx means your own web server timed out. A CDN-branded page that names your host means the CDN timed out waiting for your origin.

nginx logs the timeout with the address it was waiting for:

upstream timed out (110: Connection timed out) while reading response header from upstream,
upstream: "fastcgi://unix:/run/php/php8.3-fpm.sock", request: "GET /reports HTTP/2.0"

Now you know which page is slow and which part of the stack kept it waiting. The next step is finding out why.

Common causes and how to fix them

Slow database queries

The most common reason. A query that took 50 milliseconds with a thousand rows takes 40 seconds with a million, because it scans the whole table. Turn on the slow query log and look for the page’s queries:

# MySQL / MariaDB
SET GLOBAL slow_query_log = 'ON';
SET GLOBAL long_query_time = 1;

# PostgreSQL, in postgresql.conf
log_min_duration_statement = 1000

Run the slowest query with EXPLAIN and look for full table scans. A missing index is the usual fix. Locks are the other usual suspect: a long transaction or a migration can hold a table while every request that needs it waits.

Slow external APIs

Pages often call other services while they’re being built: a payment provider, a shipping calculator, a search engine, a CRM. If that service is slow, your page is slow, and your proxy times out. Set a short timeout on every outgoing call, a few seconds rather than the library default, and decide what the page shows when the call fails. A shipping estimate that says “calculated at checkout” is better than a 504.

Keep an eye on the services you depend on. Uptimecheck’s third-party monitoring follows the status pages of 31 services such as Klarna, Shopify and Cloudflare, so a slow provider shows up next to your own checks.

Too few workers for the traffic

When every worker is busy, new requests wait in a queue. They aren’t slow themselves, they are waiting their turn, and the proxy’s clock is running the whole time. PHP-FPM says so in its log with server reached pm.max_children. More workers help only if the server has memory and CPU for them. Often the better fix is making each request shorter, so the same workers serve more of them, and caching pages that don’t change per visitor.

Long jobs inside a web request

Exports, imports, report generation, image processing and sending hundreds of emails don’t belong in a web request. They take as long as they take, and sooner or later one of them crosses a timeout. Move them to a background queue: the request starts the job and returns at once, and the page polls for the result or the user gets an email when it’s done.

The server itself is overloaded

High CPU, memory pressure that pushes the server into swap, or a disk that can’t keep up make everything slow at once. A 504 on every page, not just one, points here. Look at CPU, memory, swap and disk wait for the same period:

uptime
free -m
iostat -x 5 3

Server monitoring keeps that history, so you can see what the server was doing at the minute the 504s started instead of guessing afterwards.

Network problems between the layers

If the proxy can’t reach the upstream at all, for example because a firewall drops packets instead of rejecting them, the connection hangs until it times out. That ends in a 504 rather than a 502. Check that the proxy can open a connection to the upstream’s address and port from the same machine.

When raising the timeout is right

Sometimes a request is legitimately long: a large upload, a report an admin asks for once a month. Then raise the limit for that path only, and keep the layers in order so the outer ones wait longer than the inner ones:

location /admin/exports/ {
    proxy_read_timeout 300s;
    proxy_pass http://app;
}

Raising the limit for the whole site doesn’t fix slow pages. It makes visitors wait longer before they see an error, and it lets slow requests hold workers for longer, which makes the queue worse for everyone else.

How monitoring catches 504s

A 504 rarely comes out of nowhere. The page got a little slower every week as the data grew, until one day it crossed the limit. That’s good news, because it means you can see it coming.

  • Watch the response time, not only the status. Uptimecheck records the response time of every check, split into DNS, connect, TLS, server and download, so you see whether the server got slower or the network did. A slow-response alert tells you when a page crosses the limit you set, long before the proxy’s timeout. Our guide to what a good response time is helps you pick the limit.
  • Confirm failures before alerting. Checks run every minute from Stockholm, Sweden, and every failure is confirmed by a second check, so one slow request doesn’t wake anyone up.
  • Monitor the slow pages directly. Search, checkout, account pages and reports are where 504s happen, and they are rarely the homepage. Add uptime monitors for them, with a timeout that matches what a visitor will put up with.

504 checklist

  1. Time the request: a round number of seconds tells you which limit fired.
  2. Read the headers and error page to see which layer timed out.
  3. Find the slow page in the proxy’s error log.
  4. Look for slow queries, locks and slow external calls for that page.
  5. Check workers, CPU, memory, swap and disk for the same minutes.
  6. Fix the slow part, cache it or move it to a background job.
  7. Raise timeouts only for paths that are legitimately long, outer layers longer than inner ones.
  8. Alert on slow responses so the next 504 is seen while it’s still a slowdown.

Questions

What is the difference between a 504 and a 502?

A 504 means the proxy waited and got no answer in time. A 502 means it got an answer that was invalid, or the connection was refused or closed. A 504 usually points at something slow, a 502 at something broken or not running.

Should I just increase the timeout?

Only as a short-term measure, and only when the work is legitimately long, like an export. A page that needs 90 seconds will still feel broken to the visitor. Find the slow part and fix it, cache it or move it to a background job.

Why does the 504 come after exactly 60 seconds?

60 seconds is a common default, for example nginx's proxy_read_timeout and many load balancers' idle timeout. An error at a round number of seconds tells you which layer's limit fired.

Can a 504 happen when my server is fine?

Yes. If your page waits for a payment provider, a search service or another API, and that one is slow, your server waits too and the proxy in front of it times out. Monitor the services you depend on as well as your own.

Does a 504 on Cloudflare mean Cloudflare is down?

Usually not. Cloudflare returns 504 when your origin did not answer in time. Check the origin's response time and logs first.

Keep reading

Guides 5 min read

500 Internal Server Error: How to Find and Fix the Cause

A 500 Internal Server Error means the application failed while handling the request. Where to find the real error message, the causes behind most 500s and how to make sure you hear about them first.

Read

Guides 6 min read

502 Bad Gateway: What It Means and How to Fix It

A 502 Bad Gateway means a proxy, load balancer or CDN got no valid answer from the server behind it. How to find which layer failed, fix the usual causes and catch the next 502 before customers do.

Read

Downtime is obsolete.

Set up your first monitor in under a minute, or look around the live demo first.

14-day free trial · No credit card required

Start free trial