504 Gateway Timeout

504 Gateway Timeout Under Load: Fix Nginx PHP-FPM

Server & Cloud Intermediate 👁 7 views 📅 Jun 25, 2026

A 504 under load means your app can't respond fast enough. Usually it's PHP-FPM or Nginx timeout settings. I'll show you the real fix.

Quick Answer

Raise fastcgi_read_timeout in Nginx and max_execution_time in PHP-FPM. Also check PHP-FPM's pm.max_children setting. That's the short version.

Context

You get a 504 Gateway Timeout when your web app runs a script that takes too long to finish. Under load, this happens because PHP-FPM processes get busy, and the server gives up waiting. I've seen this with WordPress on a shared host that suddenly gets 1000 visitors, or a custom API that processes big files. The error appears in Nginx as upstream timed out (110: Connection timed out) in logs. It's frustrating because the app seems fine on low traffic.

Most guides tell you to increase a bunch of timeouts. But the real issue is often PHP-FPM running out of workers, or a script that slows down under load. Let's fix both.

Step-by-Step Fix

  1. Check Nginx logs – Look at /var/log/nginx/error.log. Search for 504 or upstream timed out. This tells you if it's PHP-FPM or a proxy.
    sudo tail -100 /var/log/nginx/error.log | grep -i '504\|timeout'
  2. Increase Nginx timeout for PHP – Edit your Nginx server block (usually /etc/nginx/sites-available/your-site). Add or change this in the location ~ \.php$ block:
    fastcgi_read_timeout 300s;
    Then test and reload Nginx:
    sudo nginx -t && sudo systemctl reload nginx
  3. Raise PHP max execution time – Edit /etc/php/8.2/fpm/php.ini (adjust version to yours). Find max_execution_time and set to 300:
    max_execution_time = 300
    If you use a config override like /etc/php/8.2/fpm/pool.d/www.conf, add it there: php_admin_value[max_execution_time] = 300
  4. Increase PHP-FPM workers – In the pool config (same www.conf), adjust these:
    pm = dynamic
    pm.max_children = 50
    pm.start_servers = 10
    pm.min_spare_servers = 5
    pm.max_spare_servers = 20
    Save, restart PHP-FPM:
    sudo systemctl restart php8.2-fpm
  5. Also check Nginx proxy timeouts – If your app uses Nginx as a reverse proxy for Node.js or another service, add these in the location / block:
    proxy_read_timeout 300s;
    proxy_connect_timeout 75s;

Alternative Fixes

If the 504 still appears after the steps above, try these:

  • Switch to static process manager – Change pm = dynamic to pm = static and set pm.max_children to a fixed number based on your server RAM (e.g., 50 for a 4GB server). This prevents PHP-FPM from crashing under load spikes.
  • Enable slow log – Add to www.conf: request_slowlog_timeout = 10s and slowlog = /var/log/php-slow.log. Then watch that log to find which scripts are slow. Kill them or optimize.
  • Use a CDN or cache plugin – For WordPress, install a cache plugin like W3 Total Cache and a CDN like Cloudflare. This reduces PHP requests a lot.
  • Upgrade PHP version – PHP 8.2 is faster than 7.4. If you're on old PHP, upgrade. I've seen 504s disappear after moving from 7.4 to 8.2.

Prevention Tip

Monitor your server resources. Set up a cron job that checks PHP-FPM process count and alerts you if it hits 80% of max_children. Also set pm.max_requests = 500 in your pool config to avoid memory leaks. And test your app with a load testing tool like ab (Apache Bench) or wrk before going live. A 504 under load is a symptom of a bottleneck. Fix the bottleneck, not just the timeout.

Was this solution helpful?