504 Gateway Timeout Fix Ubuntu 24.04 [7 Tuning Steps]
Fix 504 gateway timeout errors on Ubuntu 24.04 by tuning Nginx, PHP-FPM, and database settings. Step-by-step performance optimization guide.

On this page
- Understanding the 504 timeout chain on Ubuntu 24.04
- Baseline monitoring before tuning anything
- Tuning Nginx proxy and fastcgi timeouts
- Matching PHP-FPM execution limits to Nginx timeouts
- Identifying and fixing slow database queries
- PHP-FPM pool exhaustion and worker tuning
- Testing changes under realistic load
- Ongoing monitoring and capacity planning
TL;DR — Key takeaways
- 504 errors occur when upstream services exceed Nginx proxy timeouts, typically 60 seconds by default on Ubuntu 24.04
- Tuning proxy_read_timeout, fastcgi_read_timeout, and PHP max_execution_time in tandem eliminates most gateway timeout issues
- Slow database queries under 5 seconds often cause intermittent 504s; enable slow query logging and add indexes to bottleneck tables
- PHP-FPM pool exhaustion triggers cascading timeouts; monitor pm.status_path to catch worker starvation before users report errors
- Always test timeout changes under realistic load and keep original config files backed up before modifying production settings
You refresh the page and see it: 504 Gateway Timeout. Your application worked fine yesterday. Traffic hasn't spiked. The server is online. What changed?
In most support tickets I handled, the culprit was a mismatch between Nginx proxy timeouts and actual upstream processing time. Ubuntu 24.04 ships with sensible defaults, but those defaults assume your backend responds in under 60 seconds. When PHP scripts run longer, database queries slow down, or worker pools saturate, timeouts cascade through your stack. This guide walks through identifying bottlenecks and tuning each layer to eliminate 504 errors without blindly raising limits.
Understanding the 504 timeout chain on Ubuntu 24.04
A 504 error means Nginx received no response from the upstream service within the configured timeout window. The chain looks like this: client request hits Nginx, Nginx proxies to PHP-FPM or an application server, that service queries a database or external API, then the response travels back. Any link in that chain can bottleneck.
Ubuntu 24.04 runs Nginx 1.24 by default with proxy_read_timeout set to 60 seconds. PHP 8.3 sets max_execution_time to 30 seconds in the default php.ini. If your PHP script needs 45 seconds to generate a report, PHP finishes successfully but Nginx already gave up at 60 seconds and returned a 504 to the user.
Check your current Nginx timeout with grep -r 'proxy_read_timeout\|fastcgi_read_timeout' /etc/nginx/. If you see nothing, the 60-second default is active. Check PHP with php -i | grep max_execution_time. Mismatched values cause intermittent failures that appear random but follow a pattern: slow operations fail, fast ones succeed.
Baseline monitoring before tuning anything
Record average response times with tail -f /var/log/nginx/access.log | awk '{print $NF}' to watch request durations in real time. Anything over 5 seconds is a red flag. Over 30 seconds and you're headed for timeouts.
- location /nginx_status { stub_status on; access_log off; allow 127.0.0.1; deny all; }
- Reload Nginx and curl http://localhost/nginx_status to see active connections and request counts
- For PHP-FPM, edit /etc/php/8.3/fpm/pool.d/www.conf and uncomment pm.status_path = /status
- Add location ~ ^/(status|ping)$ { access_log off; fastcgi_pass unix:/run/php/php8.3-fpm.sock; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; } to your Nginx config
- Curl http://localhost/status?full to see worker pool state
Tuning Nginx proxy and fastcgi timeouts
Test the config with sudo nginx -t. If it reports syntax ok, reload with sudo systemctl reload nginx. The 180-second fastcgi_read_timeout gives PHP three minutes to respond. Don't go beyond 300 seconds; if your application needs more than five minutes per request, the problem isn't timeout configuration.
For reverse proxy setups (Nginx in front of Node.js, Python, or Go), use proxy_read_timeout 180; instead. The principle is the same.
- fastcgi_connect_timeout 60;
- fastcgi_send_timeout 180;
- fastcgi_read_timeout 180;
Matching PHP-FPM execution limits to Nginx timeouts
Check pool configuration in /etc/php/8.3/fpm/pool.d/www.conf. The pm settings control worker availability. If pm.max_children is too low, requests queue and eventually time out even with generous limits. A server with 4GB RAM can safely run pm.max_children = 20 for typical WordPress or Laravel workloads. Monitor /status?full after changes to see if workers saturate.
Identifying and fixing slow database queries
For application-level caching, configure opcache properly. Check /etc/php/8.3/fpm/conf.d/10-opcache.ini and verify opcache.enable = 1. Set opcache.memory_consumption = 128 for most sites. Restart PHP-FPM after changes.
- slow_query_log = 1
- slow_query_log_file = /var/log/mysql/slow-query.log
- long_query_time = 2
PHP-FPM pool exhaustion and worker tuning
Restart PHP-FPM and monitor /status again under load. If active processes consistently hit max_children, increase it by 25% and test. Each worker consumes 30-70MB depending on your application.
Set pm.max_requests = 500 to recycle workers periodically and prevent memory leaks in long-running processes.
- pm = dynamic (keeps memory usage reasonable)
- pm.max_children = 20 (total workers; RAM / 50MB is a safe estimate)
- pm.start_servers = 5
- pm.min_spare_servers = 3
- pm.max_spare_servers = 8
Testing changes under realistic load
For production deployments, apply changes during low-traffic hours. Keep your backup configs handy. If errors spike after deployment, revert with sudo cp /etc/nginx/sites-available/default.bak /etc/nginx/sites-available/default && sudo systemctl reload nginx.
Ongoing monitoring and capacity planning
Review PHP-FPM pool status weekly. If max_children is hit frequently, scale vertically (more RAM, more workers) or horizontally (add application servers behind a load balancer). Check memory usage with free -h before adding workers—swapping kills performance worse than queuing.
Database query performance degrades as tables grow. Re-run slow query analysis monthly and add indexes proactively. Archive old data to keep working sets small.
Quick troubleshooting checklist
- Check Nginx error logs at /var/log/nginx/error.log for upstream timeout entries
- Verify current proxy_read_timeout and fastcgi_read_timeout values in Nginx config
- Compare PHP-FPM max_execution_time with Nginx timeout settings
- Enable MySQL slow query log and identify queries exceeding 2 seconds
- Monitor PHP-FPM pool status to detect worker saturation
- Test timeout changes on staging environment before production deployment
- Document baseline response times before and after tuning
- Set up continuous monitoring for upstream response times
FAQ
What causes 504 gateway timeout errors on Ubuntu 24.04?
A 504 gateway timeout occurs when Nginx or Apache waits for an upstream service (PHP-FPM, application server, or database) longer than the configured timeout limit. The default proxy_read_timeout in Nginx is 60 seconds. If your PHP script or database query takes 65 seconds, Nginx terminates the connection and returns a 504 error to the client.
How do I increase Nginx timeout for slow backend processes?
Edit your Nginx server block and add proxy_read_timeout, proxy_connect_timeout, and proxy_send_timeout directives. Set proxy_read_timeout to 300 for five-minute tolerance. For PHP-FPM backends, use fastcgi_read_timeout instead of proxy_read_timeout. Reload Nginx with sudo systemctl reload nginx after changes. Always verify PHP max_execution_time matches or exceeds the Nginx timeout.
Should I increase timeouts or optimize the slow code first?
Optimize the slow code first. Increasing timeouts masks performance problems and delays failure under high load. Profile your application, enable MySQL slow query logging, add database indexes, and implement caching. Raise timeouts only after optimization when legitimate long-running tasks (report generation, data exports) require extended execution time.
Related articles
- Hosting OperationsSelf-Hosted App Deployment Fails? Check DNS, SSL, Reverse Proxy, and Logs FirstTroubleshoot failed self-hosted app deployments by checking DNS, SSL, reverse proxy routing, container status, logs, and ports.
- Hosting OperationsSelf-Hosted PaaS on a VPS: What to Check Before Installing Coolify, Dokploy, or CapRoverA hosting support checklist for preparing a VPS before installing self-hosted PaaS tools like Coolify, Dokploy, or CapRover.
- Hosting OperationsLinux Server Security Lessons from the Arch Linux Malware Package IncidentPractical Linux server security checklist for VPS admins after package malware concerns, with safe checks, rollback steps, and support guidance.
- Hosting OperationsAWS Lightsail Hong Kong VPS Latency: Practical Hosting Guide for IndonesiaLearn how to test AWS Lightsail Hong Kong VPS latency, compare regions, migrate safely, and troubleshoot hosting performance.
- Hosting OperationsCloudflare Tomorrow Watchlist: A Practical Hosting Operations GuidePractical Cloudflare troubleshooting checklist for DNS, SSL, caching, WAF, origin health, safe testing, and rollback planning.
- Hosting OperationsNetwork Safety Checklist for AI Agent Skills in Hosting OperationsAudit AI agent skills safely with network checks, secret protection, sandbox testing, rollback steps, and hosting support troubleshooting guidance.