Troubleshooting gateway errors and timeouts: 502, 504
This article can help you troubleshoot issues related to 504/502/gateway errors. When troubleshooting, it can be helpful to understand how the processing works between nginx and PHP, which is often used for high performance web application hosting, like WordPress.
Common errors that occur that are connected to this configuration:
- 504 Gateway Timeout
- Gateway Timeout (504)
- HTTP Error 504 – Gateway Timeout
- Gateway Timeout Error
- 502 bad gateway
- Bad Gateway
Why is there a gateway?
When a request comes through a web browser, it first hits nginx, our lightweight front-end web server and nginx then decides where the request should go from there, like a train conductor. Nginx will usually handle simpler requests for resources (like images and cached pages) itself, while sending requests for dynamic pages (like a WordPress admin page or shopping cart) through to apache (for modsecurity and .htaccess processing) and then PHP. It looks like this:
nginx -> apache -> php-fpm
nginx acts as a gateway sending the right types of requests through to apache and PHP. If there’s a problem ‘downstream’ — such as with apache or php — you will get a gateway error, like 502 Bad Gateway or 504 Gateway Timeout.
This problem could be extremely slow running code, or an actual issue with the apache or PHP service, though with our hosting the issue is most commonly a code problem.
Use server logs to get more info
To help pinpoint the cause of the gateway error, check the logs to see what’s being reported. sometimes the logs will simply report a 502 or 504 error — just like you’re seeing in the browser — which won’t be helpful. But sometimes you might see an error or warning logged just prior to the Gateway error that will pinpoint what plugin or theme is causing the error.
You can learn how to use Plesk to view logs here. If you can use those errors to get to the bottom of the issue, then definitely do so! Otherwise read on for additional ways to narrow things down.
Help! I can’t even access my website’s admin area! (Like wp-admin for WordPress)
Sometimes when you’re receiving constant Gateway errors, you are unable to access your website’s admin area (like WordPress’s wp-admin), yet you find you need to do so to help troubleshoot this issue. The only way to regain access is to block access until you can get the issue resolved.
To block access, you can proceed in one of two ways: 1) block access to the particular part of the site that’s eating up resources, or 2) you can block access to all IPs except your own temporarily to regain access.
To block access to all IPs except your own (easier)
Login to Plesk and visit the apache & nginx settings page. Under “Deny access to the site” enter a custom value and make it "*
“ (without the quotes). Then under “Excluding” enter your own IP address and save the changes. You may need to wait up to 3 minutes after saving your changes for the server to restart (~1m) and for any PHP processes that were running to reach their timeout (~2m).
Be sure to remove this block when you’re done troubleshooting.
To block access to the resource intensive request (more complex)
If there’s only one page or resource on the site that’s creating this problem (like a single page that loads slowly), use the logs to identify that particular request URI. Then add the following code snippet to the top of your .htaccess file to block the problematic resource (even just temporarily) so you can access the admin panel. Replace filename\.php
with the actual request URI shown in the logs (this is the part that comes after the domain). If there are dots in the file path be sure to prepend them with a backslash as seen in the example.
<FilesMatch filename\.php> Order Allow,Deny Deny from all </FilesMatch>
A One-Time Fix for Gateway Errors
If the issue was just a one-time thing (e.g.: you ran a script and it wouldn’t stop running), the solution is to directly restart the underlying services, which forces that script to end.
If you don’t have root access to the server or admin access to Plesk, then you can trigger a restart of PHP services by making a change to your PHP configuration in Plesk. Login to Plesk and visit the “PHP Settings” button for your domain, then make a small change there (like increasing the memory limit by 4MB) then save your changes. This update triggers a restart of apache and PHP processing and could resolve your error! Note: it may take up to 3 minutes (or longer depending on your provider) for the changes to take effect.
If that doesn’t do the trick or the issue returns, you’ll need to go through the following possible causes/symptoms to determine which best fits your case.
Common Causes and Quicker Solutions
Enable a page caching solution
If you do not currently use a page caching plugin like WP Super Cache (free) or WP Rocket (paid), installing and activating an optimization plugin will very likely resolve this issue.
If you’re not using WordPress, look for the option to enable page caching and/or object caching in your content management system.
Caching solutions save the contents of each page as a simple text file so they do not need to be dynamically generated each time. This single change can take a site from a 10 active user max to thousands.
I’m trying to run an export, import, or large report that takes a while
If your site is running normally, but every time you try to run a large export, import, or report for your site’s data, you get gateway errors, this is because you’re reaching timeouts before the report can be processed. Although there’s no super simple way to fix this long term, there is a way to fix it short term: temorarily increase the timeouts.
You can do this in Plesk control panel by following the steps in our guide on how to change a PHP setting. You will need to change the values (they’re in seconds) for max_execution_time
and max_input_time
to something like 300 to allow processes to run for 5 minutes. Do not forget to change those values back after you have completed your long-running action.
Why can’t you just increase the timeouts permanently?
Technically you can, however increasing timeouts permanently will very likely detrimentally affect the performance of your site. Timeouts default to values like 30 or 60 seconds with intention: if a process takes that long to complete, and you trigger too many long running processes, they can eat up all available processing slots and bring your entire site down for all visitors. Therefore keeping your timeout values around 30-60s ensures this can only happen for at most that amount of time.
Nearly every request to my site or homepage takes >10s to process
You’ll know if this is the issue if one or more pages on the site take longer than ~10s to even begin loading, with your browser showing nothing until that 10+ second period has passed.
There are two common reasons this can occur:
1) Code Performance Issues: you’ve got some code running on the site that is not optimized for performance or having a problem. An example of this would be an infinite loop in the code, or something that tries to pull millions of database records in one query (rather than retrieving them in batches). The first thing to check is any code that has been recently added to the site, like plugins, a new theme, custom code, etc. You’ll probably want to get your developer involved to help narrow this down. We have a KB article with some commonly recognized versions of this, however if you’re not able to determine the cause with those suggestions, then your remaining option is exhaustive troubleshooting. We have a guide to exhaustive troubleshooting with WordPress here.
2) Slow or Non-Responding External Resource Requests: Some PHP code is trying to communicate with an external resource (hosted elsewhere) that’s taking too long to respond or not responding at all. To solve issues with External Resources, you’ll need to look into what parts of your website’s PHP code (custom code or plugins/theme code) are trying to retrieve external resources. This is most commonly code that connects to a 3rd party service like a payment processor or weather data retrieval via an API or scraping. Here’s a few examples:
- Some payment gateways, or XML API services use non-standard ports (though it’s very uncommon these days as standard ports are used far more frequently now). If it’s not using port 80 or 443, it’s likely trying to communicate on a blocked port and failing.
- Older twitter widgets have been known to retrieve tweets using back-end code and then failures to connect to the Twitter servers cause hang-ups like this. This does not apply to Twitter’s own feed embeds that operate via Javascript asynchronously.
If you’re using WordPress or any other CMS with plugins, be sure to try disabling any plugin that might communicate externally to see if it solves the problem.
If you’re not able to determine which plugin might be at fault intuitively, then your remaining option is exhaustive troubleshooting. We have a guide to exhaustive troubleshooting with WordPress here.
Optimization Plugin using too many resources (examples: JetPack Boost or Hummingbird)
If you use JetPack Boost or Hummingbird, try disabling it. These optimization plugins put heavy load on the server by still requiring a PHP process for each page request.
Instead, we recommend trying WP Super Cache or WP Rocket as per our guide to improving WordPress performance performance as these plugins allow bypassing PHP altogether for most page requests.
Limited Web Server Buffers (not an issue on Websavers hosting)
Apache or PHP processes may be generating larger data sizes than nginx is allowed to process. Since apache and PHP both need to pass this data through nginx to reach the website visitor, it generates a 502 error indicating “Upstream sent too big header”. We’ve seen this error with customers using the WordPress plugin OptInMonster, however any software could do it.
Our shared hosting should already be optimized with larger buffers for nginx, however if you have your own VPS, or are not hosted with us, you’ll need to apply these values yourself to the nginx configuration:
fastcgi_buffers 128 4096k; fastcgi_buffer_size 4096k;
This tells nginx that it’s okay for it to accept large (4MB) headers. You can insert these into a file like: /etc/nginx/conf.d/increase_buffers.conf
then restart nginx to apply the changes. Example:
echo 'fastcgi_buffers 128 4096k; fastcgi_buffer_size 4096k;' > /etc/nginx/conf.d/increase_buffers.conf
PHP-FPM Misconfigured or Needs Tuning (VPS/Dedicated Server Only)
Sometimes if you’re getting constant Gateway Timeout errors, and the only thing that clears them up is restarting PHP (as described above), or if you’re on a VPS and you see your PHP processes staying running at high CPU and lasting far longer than they should (or you’ve been told that’s what is happening by server techs), you will need to take some steps to rein them in.
Note: if you’re on our shared hosting, our PHP-FPM configuration is already optimized for a shared hosting environment and so if you’re experiencing gateway errors, this solution will not apply.
The following are some options that have worked for us, however it’s super important to note that these are workarounds to the real issue. Identifying the code that isn’t responding fast enough, and optimizing its performance is the true solution.
- PHP-FPM allows you to tune the PHP Process Manager (FastCGI Process Manager = FPM) by making some changes in Plesk. If you’re using the “ondemand” style PHP-FPM process, you may want to reduce the number of requests each process handles before gracefully exiting / restarting a new process. This is labelled as pm.max_requests. Try 100 or 150 if you’re having performance issues
- If your PHP processes aren’t dying off, you may need to *make* them die. There’s a couple good ways to do this. First is to definitely set an idle timeout for the PHP-FPM processes by setting pm.process_idle_timeout – try setting it to 10s (you can do this in the field below the FPM settings.
- If your PHP processes still aren’t dying off, you may need to get even more aggressive with them. Try setting request_terminate_timeout to a few seconds higher than your max_execution_time setting. If max_execution_time doesn’t kill off the process, request_terminate_timeout certainly will.
Too many PHP processes needed to serve requests
If you’ve reached this point then it’s likely that your site, as it currently is configured, requires more dedicated PHP processing resources than the existing hosting service provides.
This means your #1 goal must be reducing the amount of dynamic processing that needs to occur on each page load.
- If you’re using WordPress see here to learn how to utilize and optimize a page cache. Using the right performance plugin can make a huge difference in server processing speed and instantly help prevent Gateway errors.
- If you already have caching enabled, the next step is to detect and reduce cases where dynamic processing is occurring.
If you found this guide helpful, check out the other guides and posts available. If you’re in need of a high-performance Canadian web host or VPS hosting partner, check out our services!
Posted in Advanced
About Websavers
Websavers provides web services like Canadian WordPress Hosting and VPS Hosting to customers all over the globe, from hometown Halifax, CA to Auckland, NZ.
If this article helped you, our web services surely will as well! We might just be the perfect fit for you.
@Jordan, had the same issue in my previous website but it is fine now.
Great! What solved it in your case?