What 504 means
A gateway or proxy forwarded the request to the server behind it (the upstream) and didn't get a response in time. 504 is defined in RFC 9110 §15.6.5. The upstream may still be working on the request; the proxy simply stopped waiting.
HTTP/1.1 504 Gateway Time-out
Server: nginx
Content-Type: text/html
<html><head><title>504 Gateway Time-out</title></head>...
Compare with 502: 502 is a bad or missing answer, 504 is a late one.
Common causes
- Slow application code: an unindexed database query, a report built on the fly, a large export or import.
- A slow dependency: the app waits on an external API, a lock or a saturated database.
- All workers busy: requests queue behind long ones in PHP-FPM, Gunicorn or Puma until the proxy gives up.
- Network problems between proxy and upstream: a firewall dropping packets, an upstream on an unreachable address.
- Timeouts that don't line up across layers: CDN, load balancer, nginx and the app each have their own.
How to fix it
nginx. The error log line is upstream timed out (110: Connection timed out) while reading response header from upstream. The relevant settings, all 60 seconds by default:
location / {
proxy_pass http://app:3000;
proxy_connect_timeout 5s; # establishing the connection
proxy_read_timeout 120s; # between two reads of the response
proxy_send_timeout 60s; # between two writes of the request
}
location ~ \.php$ {
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
fastcgi_read_timeout 120s;
}
Raise them only for the routes that need it, and remember PHP has its own limits: max_execution_time in php.ini and request_terminate_timeout in the FPM pool. If PHP stops first, you get a 502 or 500 instead.
Apache with mod_proxy. ProxyTimeout (defaulting to Timeout, 60 seconds) controls how long it waits for the backend.
Fix the slowness, not just the timeout. Profile the slow request, add the missing index, cache results, and move work that takes minutes to a background job that the page polls. Longer timeouts only tie up workers for longer.
Line up the layers. Each layer in front should wait slightly longer than the one behind it. If the CDN gives up first, you see its error instead (Cloudflare's is 524, after 100 seconds).
504 and SEO
Google counts 504 as a server error. Occasional timeouts are harmless, but frequent ones make Googlebot slow down its crawling, and pages that keep timing out are eventually dropped. Slow responses alone also reduce how much Google crawls, so a page close to timing out is already costing crawl budget.
Related codes
- 502 Bad Gateway: the upstream answered badly or refused the connection.
- 524 A Timeout Occurred: Cloudflare's timeout waiting for the origin.
- 522 Connection Timed Out: Cloudflare couldn't even connect.
- 408 Request Timeout: the client was too slow, not the server.
Time a request to the page with the HTTP Request Builder, or check every hop's status with the Redirect Checker.