Ffile2fix
Sign in Get started

How to fix Nginx "upstream timed out (110: Connection timed out)"

upstream timed out (110: Connection timed out) while reading response header from upstream, client: 203.0.113.5, server: example.com, request: "POST /wp-admin/admin-ajax.php HTTP/1.1", upstream: "fastcgi://unix:/run/php/php8.3-fpm.sock", host: "example.com"

Nginx passed the request to PHP-FPM or a proxied app and waited for the default 60 seconds without getting response headers back. Visitors see a 504 Gateway Timeout. The cause is almost always a slow script, slow database query or slow external API call.

Also appears as: upstream timed out (110: Connection timed out) while connecting to upstream · upstream timed out (110: Operation timed out) while reading upstream · upstream timed out (110: Connection timed out) while reading response header from upstream, upstream: "http://127.0.0.1:3000/api/report" · 504 Gateway Time-out

Common causes

  • A PHP script runs longer than fastcgi_read_timeout (60s by default)
  • Slow or locked MySQL queries
  • External API calls with no timeout
  • All PHP-FPM workers busy, so new requests wait in the queue
  • 'while connecting to upstream' means the backend host or port is unreachable
  • Heavy reports, imports or backups run in a web request

How to fix it

  1. Note which phase timed out. 'while connecting to upstream' means Nginx could not reach the backend; check it is running and reachable. 'while reading response header' means the backend accepted but answered too slowly.
  2. Find the slow code. Enable the PHP-FPM slow log: request_slowlog_timeout = 10s and slowlog = /var/log/php8.3-fpm-slow.log in the pool config. Restart PHP-FPM and read the stack traces.
  3. Check the database. Run SHOW FULL PROCESSLIST; in MySQL during the slowdown. Long-running or locked queries point to missing indexes or lock contention.
  4. Check worker capacity. Look in the PHP-FPM log for 'server reached pm.max_children'. If you see it, requests are waiting for a free worker; tune pm.max_children to your RAM.
  5. Raise the timeout for known long tasks. Set fastcgi_read_timeout 300s; (or proxy_read_timeout 300s; for proxy_pass) in the specific location, and match PHP's max_execution_time and request_terminate_timeout.
  6. Move heavy work to the background. Run imports and exports with a queue or cron job so the HTTP request returns quickly.

Raise read timeouts for one slow endpoint only

location = /wp-admin/admin-ajax.php {
    include snippets/fastcgi-php.conf;
    fastcgi_pass unix:/run/php/php8.3-fpm.sock;
    fastcgi_read_timeout 180s;
}

location /api/report {
    proxy_pass http://127.0.0.1:3000;
    proxy_read_timeout 180s;
}

How to stop it happening again

  • Profile slow endpoints before raising timeouts
  • Index columns used in WHERE and JOIN clauses
  • Set timeouts on all outbound HTTP calls
  • Monitor PHP-FPM worker usage

Frequently asked questions

What is the default Nginx upstream timeout?

fastcgi_read_timeout and proxy_read_timeout both default to 60 seconds. They measure time between two reads, not the whole response.

Why does admin-ajax.php time out in WordPress?

A plugin is doing heavy work in an AJAX call, such as a backup, import or page builder save. Find the plugin with the PHP-FPM slow log.

Should I just set the timeout to 3600s?

No. Very long timeouts tie up workers and make outages worse. Raise it only for specific endpoints that need it.