# 504 Gateway Timeout: what it means and how to fix it

> A 504 means the upstream didn't answer in time - too slow, not dead. How to find the slow hop, and why raising the timeout is rarely the fix.

Published: 2026-07-27 | Updated: 2026-08-09 | Canonical: https://yoping.me/guides/504-gateway-timeout

A 504 and a 502 are siblings with different tempers. A
[502](/guides/502-bad-gateway) means the upstream answered *wrongly*; a
504 means it didn't answer *in time*. The proxy waited - typically 30 or
60 seconds - gave up, and told you so. Something behind it is alive but
too slow.

## What's actually being slow?

The request chain is usually browser to CDN to proxy to app to database, and
a 504 means one link exceeded the link in front of it. The classic
culprits, most common first:

- **A database query gone quadratic** - a missing index, a lock queue, a
  table that grew past its plan.
- **A downstream API call with no timeout of its own** - your app waits
  forever on a third party, so your proxy times out on your app.
- **CPU or memory saturation** - the app is thrashing and everything
  takes 40x normal.
- **Cold starts** - serverless or just-restarted apps paying startup cost
  on the first requests.

## How do I find the slow hop?

Time each layer independently:

```
# Total, through the front door - where does the time go?
curl -s -o /dev/null -w 'dns %{time_namelookup}  connect %{time_connect}  ttfb %{time_starttransfer}  total %{time_total}\n' https://example.com

# The app directly, from its own box
curl -s -o /dev/null -w 'ttfb %{time_starttransfer}\n' http://127.0.0.1:3000/

# The database, from the app's box
time psql -c 'SELECT 1'
```

A high time-to-first-byte at the app layer with a fast database points at
application code. Fast app-direct but slow through the proxy points at
the proxy's own config or a saturated connection pool between them.

## Should I just raise the timeout?

Usually no. The proxy's timeout is a circuit breaker, not a nuisance -
raising it converts fast failures into slow failures and ties up worker
connections while requests queue behind the slow ones. Raise it only
when the endpoint is *legitimately* slow (a report generator, an export)
and then only for that route. Fix the slowness for everything else.

## Why do 504s deserve monitoring more than most errors?

Because they creep. The query that takes 4 seconds today takes 31 seconds
after three months of table growth, and the first 504 lands at your peak
traffic hour. Response-time history shows the creep long before the
timeout: YoPingMe keeps 30 days of it on the free plan, checks from two
regions you choose, and only alerts when both agree. [Ten monitors free](https://app.yoping.me/signup) - the
slow creep stops being a surprise.
