A 504 Gateway Timeout error occurs when an intermediate server — a proxy, CDN, load balancer, or Nginx acting as a reverse proxy — waits for a response from the upstream (origin) server but doesn't receive one within the allowed time. This is a server-side problem, not a browser or network issue on your end.
Unlike the generic 500 error, a 504 specifically points to a timeout in the server chain. Here's what causes it and how to fix it.
Why does a 504 error happen?
The gateway sits between the user and the origin server. When the origin takes too long to respond, the gateway gives up and returns a 504. Common reasons include:
- The origin server is down or overloaded and can't process requests in time.
- Timeout values are too short for a task that legitimately needs more time (large report generation, bulk import, etc.).
- Slow database queries: a query taking 60+ seconds can exhaust the proxy timeout before PHP finishes.
- Unexpected traffic spikes: a flood of requests saturates the origin server.
- Network issues between servers: high latency or packet loss in the hosting infrastructure.
How to fix a 504 error step by step
Step 1: Check if it's temporary
Reload the page after 30 seconds. Occasional 504 errors caused by momentary traffic spikes or a service restart often resolve themselves within seconds or minutes.
If the error persists, move to the next step.
Step 2: Check the server error logs
Nginx and Apache error logs show exactly which upstream service failed to respond and how long the server waited. Look for lines like:
upstream timed out (110: Connection timed out) while reading response header from upstream
This tells you Nginx was waiting for PHP-FPM or an upstream Apache backend and the wait ran out.
Step 3: Increase timeout values in Nginx or Apache
If the process legitimately needs more time (bulk import, large PDF generation, etc.), increase the limits.
In Nginx (inside a location or server block):
proxy_connect_timeout 120s;
proxy_send_timeout 120s;
proxy_read_timeout 120s;
In Apache as a reverse proxy:
ProxyTimeout 120
Also update the PHP-FPM timeout to match or exceed:
request_terminate_timeout = 120s
Step 4: Check database performance
A slow query is often the root cause. Enable the MySQL/MariaDB slow query log:
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 5
If you find queries taking more than 5 seconds, check the indexes on those tables. Running EXPLAIN on a slow query will tell you if it's doing a full table scan.
Step 5: Check server resource usage
A server running at 100% CPU or out of memory can't process requests fast enough. Check resource usage:
top
free -h
df -h
If the server is habitually maxed out, it's time to scale: more RAM, a higher-tier hosting plan, or moving heavy processing to asynchronous background jobs.
504 errors in WordPress: specific causes
In WordPress, 504 errors most often appear when:
- Importing a large XML file (native importer or WooCommerce product import).
- Installing or updating many plugins at once.
- Running plugins that call slow external APIs (payment gateways, CRMs).
- Using a page builder that regenerates CSS/JS files in bulk.
In addition to raising PHP timeouts, add these lines to wp-config.php:
define('WP_MEMORY_LIMIT', '256M');
set_time_limit(300);
If the issue comes from a slow external API, consider caching those responses or processing them in a background cron job instead of inside an HTTP request.
502 vs. 504: what's the difference?
| Code | Meaning | Typical cause |
|---|---|---|
| 502 Bad Gateway | Invalid response from upstream | PHP-FPM crashed, malformed response |
| 504 Gateway Timeout | No response from upstream in time | Slow process, overloaded server, low timeout |
Both are server-side errors, but 504 specifically signals a timing problem rather than a bad response.
If these errors appear regularly, your site likely needs a deeper technical review. elenlace.com offers performance diagnostics and maintenance plans that prevent recurring outages like these.
For more tips on keeping your site fast and stable, explore our web performance guides.
Key takeaways
- A 504 error is a server-to-server timeout problem — not a user or browser issue.
- Check the error logs first: they identify which upstream service failed to respond in time.
- Raising timeout values in Nginx/Apache and PHP-FPM resolves cases where the process legitimately needs more time.
- Slow database queries are a frequent root cause; the slow query log is your best diagnostic tool.
- A server running out of resources will produce 504 errors regularly until the infrastructure is scaled up.
Still getting 504 errors on your site? Contact us at elenlace.com and our team will find the root cause and recommend a lasting fix.
FAQ
Is a 504 error my hosting provider's fault?
Not always. It can be caused by slow PHP code, a poorly optimized database query, or an unexpected traffic spike. Your hosting provider is responsible for the underlying infrastructure; you (or your developer) are responsible for ensuring your application responds within a reasonable time. The server logs clarify who is responsible in each case.
Does a 504 error affect SEO?
A brief, occasional 504 has minimal SEO impact. If Googlebot repeatedly encounters 504 errors when crawling your pages, it may reduce your crawl budget and gradually affect your rankings. Server reliability is an indirect SEO factor.
How do I know if Cloudflare is causing the 504?
If you use Cloudflare as a proxy, 504 errors can originate from two places: Cloudflare timing out while waiting for your origin server, or your server itself. Cloudflare displays its own branded 504 error page when the timeout is on its end. If the error page looks like your hosting panel or Nginx/Apache default, the problem is in your infrastructure, not Cloudflare.
What timeout value is reasonable for a normal website?
For standard page requests, 30 seconds is more than enough. For heavy operations like bulk imports or report generation, 120–300 seconds may be necessary. If a legitimate process consistently needs more than 5 minutes, consider moving it to an asynchronous background worker (cron job or queue) instead of running it inside an HTTP request.
Compare providers
Other providers and guides worth comparing: