504 Gateway Time-out: What It Means & How to Fix It

Key takeaway

A 504 Gateway Time-out means a proxy or gateway (nginx, Cloudflare, a load balancer, a CDN) waited for the server behind it and gave up: the upstream didn't answer in time. As a visitor, wait a minute and reload; the fix is the site's. As the owner, find the slow part (a query, an external API, busy PHP workers) in the logs, and check each layer's timeout: nginx waits 60 seconds by default, CloudFront 30, Google Cloud's load balancer 30, and Cloudflare 125 before it shows Error 524.

Check it now

504 gateway timeout error fix guide showing timeout chain between proxy and upstream server with troubleshooting steps
504 gateway timeout error fix guide showing timeout chain between proxy and upstream server with troubleshooting steps
Start reading
  1. What Is a 504 Gateway Timeout?
  2. What a 504 Error Looks Like
  3. How a 504 Gateway Timeout Happens
  4. Common Causes of 504 Gateway Timeout
  5. Fix for Visitors: What You Can Do
  6. Fix 1: Increase Timeout Settings (Nginx & Apache)
  7. Fix 2: Optimize Slow Scripts and Database Queries
  8. Fix 3: Check Server Resources (CPU, RAM, Disk)
  9. Fix 4: Check Error Logs
  10. Fix 5: Adjust PHP-FPM Settings
  11. Fix 6: Check CDN and Proxy Configuration
  12. Fix 7: WordPress-Specific Solutions
  13. 504 vs 502 vs 503 vs 408: What Is the Difference?
  14. Does a 504 Error Affect SEO?
  15. How to Prevent 504 Gateway Timeout Errors
  16. Frequently Asked Questions

What Is a 504 Gateway Timeout?

A 504 Gateway Timeout is an HTTP status code that means a server acting as a gateway or proxy did not receive a timely response from an upstream server. The proxy waited for the upstream to respond, but it took too long, so the proxy gave up and returned a 504 to your browser.

RFC 9110 defines it: "The 504 (Gateway Timeout) status code indicates that the server, while acting as a gateway or proxy, did not receive a timely response from an upstream server it needed to access in order to complete the request" (RFC 9110 §15.6.5).

The key word is gateway. A 504 always involves at least two servers: the one you connected to (the proxy/gateway) and the one behind it (the upstream/origin) that failed to respond. Common proxies include Nginx reverse proxy, Cloudflare, AWS Application Load Balancer (ALB), and CloudFront.

Is it 504 for everyone, or just you? Check it

What a 504 Error Looks Like

The wording depends on which layer gave up:

  • 504 Gateway Time-out with "nginx" underneath — nginx (it spells it with a hyphen)
  • 504 Gateway Time-out · The server didn't respond in time. — HAProxy's default page
  • Gateway Timeout · The gateway did not receive a timely response from the upstream server or application. — Apache in front of PHP-FPM (mod_proxy_fcgi). Apache proxying an HTTP backend shows Proxy Error · Error reading from remote server (a 502) instead.
  • ERROR · The request could not be satisfied · 504 ERROR — Amazon CloudFront
  • Error 524: A timeout occurred — Cloudflare's version: it reached your server, but the response didn't arrive in time
  • This page isn't working · example.com took too long to respond. · HTTP ERROR 504 — Chrome, when the 504 has no page of its own

Whatever the wording, the cause is the same: a proxy waited for the server behind it, and the answer didn't come in time. (Chrome uses the same "took too long to respond" line when your browser couldn't connect at all, but then the heading is "This site can't be reached" and the code is ERR_CONNECTION_TIMED_OUT, not HTTP ERROR 504: see ERR_CONNECTION_TIMED_OUT.)

How a 504 Gateway Timeout Happens

To understand the 504 error, you need to understand the timeout chain between your browser and the origin server. A typical web request passes through multiple layers, and each layer has its own timeout setting.

Here is a typical request flow: Browser → CDN (Cloudflare) → Load Balancer → Nginx → PHP-FPM → Database. If the database query takes 90 seconds and nginx's fastcgi_read_timeout is 60 seconds, nginx stops waiting and returns a 504 to the load balancer, which passes it back through the CDN to your browser.

The server that returns the 504 is usually a proxy in the middle, not the application itself. The application may still be working on the request, or it may be stuck.

LayerDefault timeoutWhat happens when it runs out
Cloudflare (Free, Pro, Business)125 secondsError 524 (Cloudflare's own code)
Amazon CloudFront30 seconds (1-120 s; more on request)504 ERROR
AWS Application Load Balancer60 seconds idle504 from awselb
Google Cloud load balancer30 seconds502 on the classic and global external load balancers; 504 on regional and internal ones
nginx (proxy_read_timeout, fastcgi_read_timeout)60 seconds504 Gateway Time-out
Apache (ProxyTimeout)Same as Timeout: 60 seconds504 with PHP-FPM (mod_proxy_fcgi); an HTTP backend gives 502 Proxy Error
PHP-FPM (request_terminate_timeout)0 (off)Worker killed: nginx gets a closed connection (502)

Sources: Cloudflare 524, CloudFront origin settings, Google Cloud, and each server's docs. PHP's own max_execution_time (30 seconds) doesn't give a 504: a script that hits it stops with a fatal error, which shows as a 500. And on Linux it doesn't count time spent waiting for the database or other I/O, so a script stuck on a slow query can run far longer than it.

Common Causes of 504 Gateway Timeout

The usual reasons a proxy gives up waiting:

  • A slow request — a heavy database query, a report, or a call to a slow third-party API takes longer than the proxy's timeout.
  • An overloaded server — CPU at 100%, memory pressure, or every PHP-FPM worker busy, so new requests wait in a queue until the proxy gives up.
  • Database bottlenecks — slow queries, missing indexes, locked tables or an exhausted connection pool.
  • Timeouts set too low — nginx's 60 seconds is too short for a backend that legitimately needs longer (an export, an import, a big upload).
  • Network trouble between proxy and origin — packet loss or a firewall that silently drops the proxy's packets (a firewall that rejects them gives 502 instead).
  • A CDN's fixed limit — Cloudflare waits 125 seconds on Free, Pro and Business, whatever your nginx allows, then shows Error 524.
  • A traffic flood — a spike or an attack ties up the workers, so ordinary requests aren't answered in time. (A server that knows it's overloaded can answer 503 instead.)

Fix for Visitors: What You Can Do

If you see a 504 error on someone else's website, the problem is on their server — not your device. However, there are a few things worth trying.

  • Wait a minute and reload — many 504s last only as long as a busy moment on the server.
  • Check whether it's down for everyone — the Website Down Checker opens the page from 11 places. If they get 504 too, it's the site.
  • Try a different network — mobile data instead of Wi-Fi, or without a VPN, in case your own proxy or VPN is the gateway that's timing out.
  • Check the site's status page or social accounts — busy sites often post about outages.

Fix 1: Increase Timeout Settings (Nginx & Apache)

The most common fix for 504 errors is increasing the timeout values on your reverse proxy. If your backend legitimately needs more than 60 seconds (the default), the proxy needs to know to wait longer.

nginx
# nginx — reverse proxy to a backend (Node.js, Python, etc.)
location / {
    proxy_pass http://backend;
    proxy_read_timeout 300;
    proxy_send_timeout 300;
}

# nginx — FastCGI (PHP-FPM)
location ~ \.php$ {
    fastcgi_pass unix:/run/php/php8.3-fpm.sock;
    fastcgi_read_timeout 300;
    fastcgi_send_timeout 300;
    include fastcgi_params;
}

# Leave proxy_connect_timeout / fastcgi_connect_timeout at their defaults:
# nginx caps them at about 75 seconds, and a dead backend should fail fast.

For Apache, add ProxyTimeout 300 in your VirtualHost or use ProxyPass / http://backend:8080/ timeout=300 for one backend.

Important: the read and send timeouts measure the gap between two successive read or write operations, not the total transfer time. So proxy_read_timeout 300 means "if no data arrives for 300 seconds", not "the whole response must finish in 300 seconds". Reload after changing them: sudo nginx -t && sudo systemctl reload nginx.

Behind a CDN, its own limit still applies: Cloudflare cuts at 125 seconds (Free to Business) and CloudFront at 30 by default, so raising nginx past them changes nothing for visitors who come through the CDN.

Fix 2: Optimize Slow Scripts and Database Queries

If your backend consistently exceeds the timeout, increasing the timeout value only masks the problem. The real fix is making the backend respond faster.

  • Find slow queries — Enable MySQL slow query log (slow_query_log = 1, long_query_time = 1) or use EXPLAIN ANALYZE on suspect queries. Add missing indexes, avoid SELECT *, and paginate large result sets.
  • Add caching — Use Redis or Memcached to cache expensive query results. A query that takes 5 seconds on every page load should be cached.
  • Move heavy work to background jobs — Report generation, email sending, image processing, and data imports should run in a job queue (Celery, Sidekiq, Bull), not in the HTTP request cycle.
  • Optimize API calls — If your backend calls slow third-party APIs, add timeouts to those calls and implement circuit breakers so one slow API does not block all requests.
  • Reduce N+1 queries — ORM-generated queries often make hundreds of individual database calls. Use eager loading or batch queries to reduce round trips.

Fix 3: Check Server Resources (CPU, RAM, Disk)

If the origin server is overloaded, it cannot process requests fast enough, and the proxy times out waiting. Check what is consuming resources.

bash
# Check CPU and memory usage
top -bn1 | head -20

# Check disk space (full disk = silent failures)
df -h

# Check memory details
free -m

# Find processes using the most CPU
ps aux --sort=-%cpu | head -10

# Find processes using the most memory
ps aux --sort=-%mem | head -10

# Check active network connections
ss -s

If CPU or RAM is at 90%+, you need to either optimize your application, kill runaway processes, or upgrade your server. If disk space is full, clear old log files, backups, or temp files — a full disk can silently crash databases and cause cascading 504 errors.

Fix 4: Check Error Logs

Error logs tell you exactly why the proxy returned 504. Always check logs before guessing at the cause.

bash
# Nginx error log (look for "upstream timed out")
tail -50 /var/log/nginx/error.log

# Apache error log
tail -50 /var/log/apache2/error.log       # Debian/Ubuntu
tail -50 /var/log/httpd/error_log          # CentOS/RHEL

# PHP-FPM log
tail -50 /var/log/php8.3-fpm.log

# System log (OOM kills, crashes)
tail -50 /var/log/syslog

Common log messages behind a 504:

"upstream timed out (110: Connection timed out) while reading response header from upstream" (nginx) — the backend took longer than proxy_read_timeout (or fastcgi_read_timeout). Speed it up, or raise the timeout if the wait is legitimate.

"upstream timed out (110: Connection timed out) while connecting to upstream" (nginx) — nginx couldn't even connect in time: a firewall dropping packets, or a backend too busy to accept connections.

"server reached pm.max_children setting" (PHP-FPM) — every worker is busy, so requests wait in the queue. Raise pm.max_children only if there's RAM for it; otherwise find the slow requests holding workers.

"Too many connections" (MySQL) — the connection limit is used up. New connections fail at once (a 500, such as WordPress's "Error establishing a database connection"), while the queries holding them are often the slow ones behind your 504s.

Fix 5: Adjust PHP-FPM Settings

For PHP apps (WordPress, Laravel, Magento), keep the timeouts in a chain, each layer slightly longer than the one behind it: nginx's fastcgi_read_timeout ≥ PHP-FPM's request_terminate_timeout ≥ PHP's max_execution_time.

SettingFileDefaultSuggested
max_execution_timephp.ini30 secondsWhat your slowest legitimate page needs (it doesn't count DB waits on Linux)
request_terminate_timeoutPHP-FPM pool config0 (off)A little above max_execution_time, as a hard stop
pm.max_childrenPHP-FPM pool config5Available RAM ÷ the size of one PHP process (check with ps)
pm.max_requestsPHP-FPM pool config0 (never recycle)500-1000, to contain memory leaks
fastcgi_read_timeoutnginx config60 seconds≥ request_terminate_timeout

After changing PHP-FPM settings, restart it (sudo systemctl restart php8.3-fpm, adjusting the version). If nginx's fastcgi_read_timeout is shorter than PHP's limits, nginx gives up first and visitors get a 504 while PHP is still working.

Fix 6: Check CDN and Proxy Configuration

If your site is behind a CDN like Cloudflare or AWS CloudFront, the CDN has its own timeout settings that can override your server configuration.

CDN or load balancerDefaultCan you raise it?Notes
Cloudflare Free, Pro, Business125 secondsNoShows Error 524, not 504
Cloudflare Enterprise125 secondsUp to 6,000 secondsCache Rule or the zone's proxy_read_timeout setting
Amazon CloudFront30 seconds1-120 seconds; more by quota requestOrigin settings → Response timeout; GET and HEAD are retried (3 attempts by default)
AWS Application Load Balancer60 secondsYesThe load balancer's idle timeout
Google Cloud load balancer30 secondsYesBackend service timeout; the classic load balancer shows 502, not 504

Cloudflare: on Free, Pro and Business, if your origin hasn't started answering within 125 seconds, Cloudflare gives up and shows Error 524 (Cloudflare). Cloudflare's own advice: speed the request up, move long jobs to the background, or serve them from a DNS-only (grey-cloud) subdomain; Enterprise plans can raise the limit.

CloudFront: raise the origin's response timeout in the distribution's origin settings (AWS). AWS suggests fixing the slow origin first. For GET and HEAD requests CloudFront retries the origin (3 connection attempts by default), so the origin can see the same request several times before the visitor gets the 504.

To see which layer sent the 504, check the response headers in the HTTP Header Checker: server: awselb/2.0 is an AWS load balancer, x-cache: Error from cloudfront is CloudFront, and server: nginx is nginx. Behind Cloudflare every response says server: cloudflare, so there the code itself (524 or 504) is the clue.

Fix 7: WordPress-Specific Solutions

WordPress sites are particularly prone to 504 errors due to heavy plugins, database bloat, and shared hosting limits. Here are targeted fixes.

  • Identify slow plugins — Deactivate all plugins, then reactivate one by one. If you cannot access wp-admin, rename the plugins folder via SSH: mv wp-content/plugins wp-content/plugins_disabled. Use the Query Monitor plugin to identify slow database queries.
  • Install a caching plugin — WP Super Cache, W3 Total Cache, or WP Rocket reduces server-side processing by serving static HTML instead of running PHP on every request.
  • Use object caching — Install Redis or Memcached and a WordPress object cache plugin. This caches database query results in memory, reducing MySQL load.
  • Clean up the database — Delete old post revisions, transients, spam comments, and orphaned metadata. Use WP-Optimize or WP-Sweep. Add define('WP_POST_REVISIONS', 5); to limit future revisions.
  • Move wp-cron to a real cron job — page visits set off WP-Cron, which runs due tasks in a loopback request that takes a PHP worker of its own. Add define('DISABLE_WP_CRON', true); to wp-config.php, then have the server run wp cron event run --due-now every 5 minutes.

504 vs 502 vs 503 vs 408: What Is the Difference?

These HTTP error codes are often confused. Here is what each one actually means.

CodeNameWhat HappenedRequires Proxy?
408Request TimeoutClient was too slow sending its request to the serverNo — server times out the client
502Bad GatewayProxy got a broken answer from upstream, or the connection was refused or closedYes
503Service UnavailableServer is overloaded or in maintenance and can't handle the request right nowNo — any server can return it
504Gateway TimeoutProxy received no response from upstream within the timeoutYes
524A Timeout OccurredCloudflare connected to the origin but got no response within 125 secondsCloudflare only (non-standard)

The critical distinction: 502 means the proxy got a broken answer, or the connection was refused or closed; 504 means the proxy's timer ran out while the upstream stayed silent. A 503 doesn't need a proxy: any server can send it when overloaded. A 408 is a client-side timeout (4xx class), where the server gave up waiting for the client.

If you see 502s and 504s together, the backend is probably struggling: requests that time out give 504, and workers that crash or get killed give 502.

If you're seeing the 502 rather than the 504, our 502 Bad Gateway guide walks through the nginx error-log messages that explain it, including a real case from this site.

Does a 504 Error Affect SEO?

Google's documentation describes what 5xx errors do (Google crawler docs):

  • Crawling slows down for the whole site, in proportion to the number of URLs returning server errors.
  • Indexed pages are kept at first, but URLs that persistently return a server error are eventually removed.
  • Crawling recovers gradually once the server answers with 2xx again.

How to Prevent 504 Gateway Timeout Errors

Prevention is better than firefighting. These practices will keep your server responding within timeout limits.

  • Set up monitoring — an uptime monitor that loads key pages every few minutes catches 504s before your users report them.
  • Match your timeout chain — Ensure CDN timeout ≥ proxy timeout ≥ application timeout. Mismatched values cause unpredictable 504 errors.
  • Implement health checks — Load balancers and proxies should health-check upstream servers and route traffic away from unresponsive instances.
  • Use caching aggressively — Cache static assets, API responses, and database queries. A cached response is never slow enough to cause a 504.
  • Auto-scale — Use horizontal scaling (more instances) so that traffic spikes do not overwhelm a single server.
  • Offload heavy work — Move file processing, report generation, email sending, and bulk imports to background job queues. Never do expensive work inside an HTTP request.
  • Monitor slow queries — Enable slow query logging in MySQL/PostgreSQL. Set alerts for queries exceeding 1 second.
  • Keep dependencies healthy — Monitor third-party APIs your backend depends on. Add timeouts and circuit breakers so one slow API does not cascade into 504 errors for all users.

Check if a server is returning 504

DNS Robot's free HTTP Header Checker requests any URL from our server and shows the status code and headers. server: awselb/2.0 means an AWS load balancer answered, x-cache: Error from cloudfront means CloudFront. Behind Cloudflare every response says server: cloudflare, so there the code (524 or 504) tells you.

Sources

  1. RFC 9110 §15.6.5: 504 Gateway Timeout, IETF
  2. Error 524: a timeout occurred, Cloudflare
  3. Origin settings: response timeout, AWS
  4. HTTP status codes and Google's crawlers, Google
  5. Troubleshooting external Application Load Balancers, Google Cloud

Frequently Asked Questions

What does 504 Gateway Timeout mean?

A proxy or gateway (nginx, Cloudflare, a load balancer, a CDN) waited for the server behind it, and the answer didn't arrive in time, so it gave up and sent you a 504. The website's server is slow or stuck; your connection is fine.

Is a 504 error my fault?

No. A 504 is a server-side error between the site's proxy and its own server. Reload after a minute, and check whether the site is down for everyone. The only local case is your own VPN or proxy timing out, which switching networks rules out.

What does "504 Gateway Time-out: The server didn't respond in time" mean?

That's HAProxy's default 504 page. HAProxy, a load balancer, waited for one of the site's servers and gave up. The fix is on the site: a slow or overloaded backend, or HAProxy's server timeout set too low.

What is the difference between a 502 and a 504 error?

Both come from a proxy. A 502 means it got a broken answer, or the connection to the upstream was refused or closed. A 504 means its timer ran out while the upstream stayed silent. 502 points to a crash or misconfiguration; 504 to slowness.

What causes a 504 error on nginx?

Usually the backend (PHP-FPM, Node.js, Python) took longer than nginx's proxy_read_timeout or fastcgi_read_timeout, 60 seconds by default. The error log says "upstream timed out (110: Connection timed out)" and whether it happened while connecting or while reading the response.

How do I increase the timeout on nginx?

In the server or location block, set proxy_read_timeout (or fastcgi_read_timeout for PHP-FPM) to the number of seconds you need, for example 300, then run sudo nginx -t and reload. The timeout counts the gap between two reads, not the whole response time.

Can Cloudflare cause a 504 Gateway Timeout?

Cloudflare shows its own Error 524 when your origin doesn't start answering within 125 seconds (Free, Pro and Business; Enterprise can raise it to 6,000). A Cloudflare-branded 504 page means your server or load balancer sent the 504; a blank, unbranded 504 came from Cloudflare itself, which is rare.

Does a 504 error hurt SEO?

Brief ones don't. Google slows crawling when it sees 5xx errors and keeps indexed pages for a while, but URLs that keep returning server errors are eventually dropped. Crawling picks up again gradually once the server answers normally.

Why does my WordPress site show a 504 error?

Usually a slow plugin or database query, every PHP-FPM worker being busy, a bloated database (revisions, transients), wp-cron running slow tasks on page visits, or a host's tight limits. Disable plugins to find the culprit, and use Query Monitor to spot slow queries.

What does a CloudFront 504 error mean?

CloudFront waited for your origin longer than its response timeout (30 seconds by default) or couldn't connect to it. For GET and HEAD it retries first (3 attempts by default). Speed up the origin, check its security groups and health, and raise the response timeout if the wait is legitimate (1-120 seconds, more by quota request).

About the author

Shaik Vahid

Founder of DNS Robot. Vahid spent years in web hosting support fixing domains, DNS records, SSL certificates and email delivery for customers. He builds DNS Robot's tools and writes these guides from the errors people actually hit.

HTTP Header Checker

Response headers exactly as sent, with a Mozilla Observatory security grade