✦ Blog

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

A 504 Gateway Timeout means your proxy or CDN gave up waiting for the app server. How to find the slow layer, which timeouts to check, and real fixes.

Upmonora team4 min read

Overview - 504 Gateway Timeout: What Causes It and How to Fix It

A 504 Gateway Timeout means a proxy forwarded your request to the application server and gave up waiting for an answer. Nothing crashed outright (that would usually be a 502). Something was simply too slow.

That makes 504s a performance problem that looks like an outage. Fixing them properly means finding the slow part, not just raising timeouts until the error goes away.

Where the timeouts live

A typical request crosses several layers, each with its own timer. The shortest one decides when the user sees an error:

LayerSettingDefault
Cloudflare (proxy to origin)Proxy read timeout100 s → error 524
AWS Application Load BalancerIdle timeout60 s → 504
Nginxproxy_read_timeout / fastcgi_read_timeout60 s → 504
Apache (mod_proxy)ProxyTimeout (falls back to Timeout)60 s
PHPmax_execution_time / FPM request_terminate_timeout30 s / off
Gunicorn--timeout30 s

If PHP kills a request at 30 seconds, Nginx sees the connection close and returns a 502. If PHP is allowed to run for 120 seconds, Nginx gives up at 60 and returns a 504. Knowing which number fired tells you where to look.

Common causes

  1. Slow database queries. A missing index, a table that grew, or lock contention. This is the most common cause.
  2. Waiting on a third-party API. Payment gateways, shipping rates, CRMs and AI APIs called synchronously, with no timeout of their own.
  3. Exhausted workers. All app workers are busy, so new requests queue until the proxy gives up. It shows as 504s across many unrelated URLs at once.
  4. Heavy work inside a web request. Exports, reports, image processing and bulk emails.
  5. Network problems between proxy and origin. Packet loss, a firewall silently dropping packets, or DNS resolution for the upstream taking too long.
  6. Cron or backup jobs at the same time. A nightly backup that saturates disk I/O makes every request slow for 15 minutes.

How to diagnose it

Is it one URL or all of them?

If only /reports/export times out, it's that request's own work. If everything times out together, it's shared capacity: workers, database or disk.

Read the logs at the right layer

# Nginx: which upstream, which request, how long
grep "upstream timed out" /var/log/nginx/error.log | tail -20

# Add timings to the access log to spot slow URLs
log_format timed '$remote_addr "$request" $status rt=$request_time urt=$upstream_response_time';

Find the slow query or call

  • MySQL/MariaDB: enable the slow query log (long_query_time = 1) and run SHOW FULL PROCESSLIST during an incident.
  • PostgreSQL: pg_stat_statements and pg_stat_activity.
  • PHP-FPM: set request_slowlog_timeout = 5s and a slowlog path to get a stack trace of anything slower than 5 seconds.

Correlate with time

504s that repeat at the same time every day are almost always a scheduled job. An uptime history showing when failures happen is often the fastest clue you have.

Fixes that work

  • Fix the slow thing. Add the missing index, cache the expensive query, paginate the huge page.
  • Set timeouts on outbound calls. Every HTTP client call to a third party needs a connect and a read timeout (a few seconds) and a fallback. Never let someone else's outage hold your workers hostage.
  • Move long work to a queue. Accept the request, return 202 Accepted, process it in the background, and notify the user when it's done.
  • Right-size workers. Enough workers to absorb normal peaks, limited by the memory you actually have.
  • Reschedule heavy cron jobs away from peak traffic, and give backups lower I/O priority (ionice -c3).
  • Raise timeouts only as a last step, only for specific routes that legitimately need it, and keep every layer consistent (app < proxy < load balancer < CDN).
# Nginx: a longer timeout for one known-slow route only
location /admin/reports/ {
    fastcgi_read_timeout 180s;
    include fastcgi_params;
    # ...
}

Catch slowdowns before they become 504s

504s rarely come out of nowhere. Response times creep up for days first - a table grows, an index stops fitting in memory - until requests start crossing the 60-second line. An uptime monitor that records response time on every check shows that trend. Upmonora's AI insights compare each monitor with its own baseline and flag the slowdown while it's still a slowdown. Pair it with our guides to 502 and 503 errors to cover all three gateway failures.

Frequently asked questions

What does 504 Gateway Timeout mean?

A server acting as a gateway or proxy (Nginx, a load balancer or a CDN) forwarded the request to the application server and did not get a response before its timeout expired.

How do I fix a 504 Gateway Timeout?

Find which request is slow and why - usually a slow database query, an external API call, or an overloaded worker pool - and fix that. Raising proxy timeouts only helps for genuinely long jobs, which are better moved to a background queue.

What is Cloudflare's timeout?

Cloudflare waits 100 seconds for the origin to respond by default and shows its own 524 error if the origin takes longer. A 504 from Cloudflare usually comes from your origin's own proxy.

Is 504 a client or server error?

Server. The 5xx range always means the problem is on the server side. A visitor can only retry later.