HTTP 408 vs 504 — Request Timeout vs Gateway Timeout Comparison

http 408 vs 504: who timed out, the client or an upstream server? Learn the difference, when each is returned, and how to debug timeouts in Nginx, ALB, and Cloudflare.

4xx

408

Request Timeout

View full 408 page →

4xx

504

Gateway Timeout

View full 504 page →

Quick Cheat Sheet

Aspect 408 Request Timeout 504 Gateway Timeout
Class 4xx — Client Error 5xx — Server Error
Who timed out? Client (didn't finish sending) Upstream server (didn't respond in time)
Issued by Origin server Reverse proxy / gateway / CDN
Client should retry? Yes, often safe Yes, with backoff

What Each Code Means

408 Request Timeout (RFC 9110 § 15.5.9) is sent when the server was waiting for the client to finish sending the request and gave up. The client took too long to produce headers or upload a body. The server is essentially saying: "I'm closing this connection because you went silent."

504 Gateway Timeout (RFC 9110 § 15.6.5) is fundamentally different: it means the responding server is itself a proxy/gateway, and the upstream server it depends on didn't respond in time. The client did everything right; the failure is downstream of the proxy.

How They Show Up in Production

You will almost never see a real 408 in modern web apps — browsers don't typically stall mid-request, and most servers just close the connection silently. 408 is most often seen with slow file uploads or flaky mobile networks.

504 is everywhere in microservice architectures:

  • Nginx returns 504 when an upstream block exceeds proxy_read_timeout (default 60s)
  • AWS Application Load Balancer returns 504 when the target group doesn't respond within the idle timeout (default 60s)
  • Cloudflare returns 504 when your origin takes longer than 100s (520-series for shorter failures)
  • API Gateway returns 504 when the integration (Lambda, HTTP backend) exceeds the integration timeout (max 29s for REST APIs)

Debugging Each

  • For 408: check client-side network logs, body size, and any expect: 100-continue flow. On the server, look for client_body_timeout and client_header_timeout in Nginx.
  • For 504: the failure is upstream — check application logs of the origin, not the proxy. Common causes: a downstream DB query, a third-party API call, or a Lambda cold start exceeding the timeout.

A Subtle Rule

If you operate a reverse proxy and your own backend takes too long, return 504 (you are the gateway). Only return 408 from the actual origin server. Many devs incorrectly send 408 from a proxy.

Real-World Use Case

When AWS ALB times out waiting for an ECS task, it returns 504 to the browser. The fix is in the ECS task (slow DB query, missing index, blocking call), not in ALB config. Conversely, 408 from an Nginx static server during a large upload usually means tuning client_max_body_size and client_body_timeout.

Look Up Any Status Code

Browse all status codes →