# HTTP 504 Gateway Timeout

**Code:** `504` · **Category:** HTTP · **Seen on:** Nginx, PHP, AWS, Cloudflare

A proxy or gateway waited too long for the upstream server to respond and gave up.

## Meaning

The upstream is reachable but slow. The proxy (Nginx, ALB, API Gateway, Cloudflare) has a read timeout — default 60s in Nginx, 60s idle on ALB, 29s on AWS API Gateway, 100s on Cloudflare (which shows 524) — and the app didn’t finish in time.

## Common causes

- Slow database query or missing index
- Long-running work done synchronously in the request (reports, imports, emails)
- Slow third-party API call without its own timeout
- Upstream overloaded and queueing requests
- Proxy timeout lower than the app’s legitimate processing time
- DNS or network issues between proxy and upstream

## Quick fix

1. Find which request is slow and why (APM, slow query log, app timing logs)
2. Move long work to a background job and return 202 + polling
3. Add timeouts to outbound calls so they fail fast
4. Only then, raise proxy timeouts if the work is legitimately long

## Detailed fix by platform

### Nginx

1. Raise timeouts (proxy or FastCGI):

```nginx
proxy_read_timeout 120s;
proxy_connect_timeout 10s;
fastcgi_read_timeout 120s;   # for PHP-FPM
```


### PHP

1. Also check `max_execution_time` and PHP-FPM `request_terminate_timeout` — whichever is lowest wins.

### AWS

1. API Gateway REST integrations max out at 29 seconds by default — use async patterns for longer work. ALB idle timeout is configurable (default 60s).

### Cloudflare

1. Cloudflare’s equivalent is 524 (100s limit on most plans).

## How to diagnose

1. **Timing** — How long does the upstream actually take for this request?
2. **Bottleneck** — DB query, external API, CPU?
3. **Timeouts** — List every timeout in the chain — the smallest one fires
4. **Load** — Is it slow only under load?

---
Source: [WhatIsMyError](https://whatismyerror.com/errors/http/504-gateway-timeout)
