Topic cluster

Performance and protocols

Keep-alive, connection pooling, buffering, timeout budgets, HTTP/2 and HTTP/3, compression and caching, and what each one costs when it is set wrong.

7 guides · cluster reviewed 8 September 2026

Proxy performance work is rarely about throughput. It is almost always about four things that are configured once, forgotten, and then produce failures that look like something else entirely: connection reuse, buffering, timeouts and caching.

Each of them has a default that was chosen for a workload that is probably not yours, and several of those defaults are older than the workload you are running. Buffering is on, which is right for slow clients and wrong for streaming. Timeouts default to sixty seconds at several layers at once, which guarantees they are not in a sensible order. And on nginx builds before 1.29.7, upstream connections are not reused at all unless you configure three separate directives correctly.

The four defaults worth changing first#

  1. Upstream keep-alive. On nginx before 1.29.7 this is off unless you configure it, which means a new TCP connection per request and, at volume, ephemeral port exhaustion. From 1.29.7 nginx caches upstream connections by default, so the first job is finding out which behaviour your build has. Keep-alive and upstream connection pooling.
  2. Response buffering. On by default, which breaks server-sent events, streaming responses and progress output. Proxy buffering and streaming responses.
  3. The timeout ladder. Almost never in the right order out of the box. Timeout budgets across a proxy chain, and the timeout ladder checker to test yours.
  4. gzip_proxied. Defaults to off in nginx, so proxied responses are not compressed at all no matter what else you set. Compression through proxies.

Shedding load rather than queueing it#

Rate limiting at the proxy is the other half of capacity management: timeouts decide how long you wait, rate limits decide how much you accept. It depends on getting the client IP right first, which is why it sits downstream of configuring trusted proxies.

Then the protocol layer#

HTTP/2 and HTTP/3 through proxies covers the part people find counter-intuitive: the protocol version is negotiated per hop, so HTTP/2 at the edge and HTTP/1.1 upstream is normal, and every bug in that translation lives at the boundary. Caching in reverse proxies is the one change that reduces upstream load rather than merely reorganising it.

Every guide in this cluster#