The defaults, and what they actually limit
The three proxy timeouts, connect, send and read, are each 60 seconds unless changed. The send and read timeouts are not deadlines for the whole exchange. They apply between two successive write or read operations, so they measure silence, not total time. An upload or download that makes steady progress can run for many minutes, while an application that computes for 70 seconds before writing a single byte will be cut off at 60. That distinction decides whether the right change is a longer timeout or an application that streams output or hands the work to a background job.
- proxy_connect_timeout: time to establish a connection with the upstream.
- proxy_send_timeout: silence while nginx sends the request to the upstream.
- proxy_read_timeout: silence while nginx waits for the upstream to send.
How nginx decides an upstream is down
For an upstream group with several servers, nginx counts failed attempts. By default one failure within a 10 second window marks a server unavailable for that window, and the counting rules come from the next-upstream setting. For a group with only one server, the documentation says the counting settings are ignored and the server is never considered unavailable, so nginx keeps trying it and every failure shows to the visitor. Teams sometimes tune max_fails on a single-server group and see no effect. If you do run several servers, a short fail window can bounce a healthy but slow server in and out of service, and a long one can keep sending traffic to a dead one.
- Single server: max_fails and fail_timeout have no effect.
- Several servers: decide how many failures in what window should take one out.
- Count only the failures you want counted by choosing the next-upstream conditions deliberately.
Retries can repeat work
proxy_next_upstream decides when a request is passed on to another server. Its default is error and timeout. When a request has already reached an upstream, nginx does not retry a POST, LOCK or PATCH unless the non_idempotent condition is added, because the first attempt may have partly succeeded. Enabling it can charge a card or create an order twice. You can also bound retries with the tries and time limits the module provides. For anything that changes data, prefer a design where the application can detect a repeated request, and leave this condition off.
- Leave non_idempotent off for payments, orders and any write.
- Add http_502 or http_504 to the retry conditions only for safe reads.
- Limit total retry time so a slow failure does not multiply the wait.
WebSockets go quiet after a minute
A WebSocket proxied through nginx needs the Upgrade and Connection headers passed explicitly, because they are hop-by-hop and nginx does not forward them on its own. The nginx WebSocket page shows setting the HTTP version to 1.1 explicitly as needed before nginx 1.29.7 and not needed from 1.29.7, so read the documentation for the version you run. Separately, nginx closes a proxied connection if the upstream sends nothing for 60 seconds, which is the read timeout. A chat or dashboard that is idle for a minute will drop. Either raise the read timeout for that location or have the application send periodic ping frames, which also detect dead connections.
- Set the Upgrade and Connection headers in the WebSocket location.
- Raise proxy_read_timeout there only, or send pings from the application.
- Check the documentation for your nginx version, since the HTTP version requirement changed at 1.29.7.
A safe change for a slow endpoint
Pick the one route that is meant to be slow, measure how long it takes under normal use, and give that location a read timeout comfortably above the measured worst case. Leave every other location at its default, so one runaway request elsewhere still fails fast. Write down the measured duration and the value chosen. If the endpoint will keep growing, schedule the real fix: run the work as a background job and let the page show progress. The fixed nginx repair job records exactly this table in its handover and refuses to raise a timeout on a route that was not failing.
Sources and limits
- nginx: ngx_http_proxy_module Checked 2026-10-11.
- Each proxy timeout defaults to 60 seconds and the send and read timeouts apply between two successive operations.
- proxy_next_upstream defaults to error and timeout; non_idempotent allows retrying POST, LOCK and PATCH after they reached the upstream.
- By default the Host and Connection headers are not passed through unchanged; Host is $proxy_host and Connection is close.
- nginx: ngx_http_upstream_module Checked 2026-10-11.
- max_fails defaults to 1 and fail_timeout to 10 seconds.
- In a group with a single server, max_fails and fail_timeout are ignored.
- nginx: WebSocket proxying Checked 2026-10-11.
- The Upgrade and Connection headers must be passed explicitly.
- By default the connection closes if the proxied server sends no data for 60 seconds; raise proxy_read_timeout or send ping frames.