Upstream Blocks: Defining Backend Pools
Nginx In Depth
Chapter 4 · Upstream Blocks: Defining Backend Pools
Web Servers Fundamentals Chapter 6 showed proxy_pass pointing at a single backend address. Once there's more than one backend instance to distribute traffic across, that single address is replaced with an upstream {} block — a named pool of servers, with real per-server behavior configurable on top.
The upstream {} Block
upstream names a group of backend servers, listed by their own address and port. That name — backend_pool here — is then used in place of a single address inside proxy_pass. Nginx distributes incoming requests across every server line inside that block, using round robin by default (Chapter 5 covers the other algorithms available).
server Entries Inside upstream
Each server line can carry its own parameters: weight shifts the distribution — a server with weight=3 receives roughly three times the traffic of a default weight=1 server, useful when backend instances have genuinely different capacity. max_fails/fail_timeout mark a server temporarily unavailable after a set number of failed attempts within a given time window, automatically routing around it until that window passes. backup marks a server as only used once every non-backup server is unavailable. down manually takes a server out of rotation without deleting its line — useful for planned maintenance, since the config still documents that server's existence.
Keepalive to Upstream Servers
Web Servers Fundamentals Chapter 9 covered keep-alive between the client and Nginx. This keepalive directive is a separate concept: it lets Nginx reuse its own already-open connections to a backend server across multiple proxied requests, rather than opening a fresh TCP connection to the backend for every single request it forwards — a real performance win on the backend-facing side, distinct from anything covered on the client-facing side.
| Parameter | Controls |
|---|---|
weight | Proportional share of traffic this server receives |
max_fails/fail_timeout | Temporarily removing a failing server from rotation |
backup | Only used once every primary server is unavailable |
down | Manually excluded, kept documented in the config |
keepalive (in upstream block) | Reusing Nginx's own connections to the backend pool |
upstream block naming a pool of backend addresses is conceptually similar to what a Kubernetes Service abstracts automatically over a set of Pods (Kubernetes Fundamentals' own territory) — both exist to let something in front of a backend pool treat "many instances" as one logical destination, just configured by hand here rather than generated automatically by an orchestrator.
max_fails/fail_timeout gives real backend health monitoring. In open-source Nginx, this mechanism is entirely reactive — it only reacts after real client requests have already failed against a server, rather than actively probing backend health ahead of time the way a dedicated health-check system does. (Nginx Plus, the paid commercial version, does add active health checks that proactively probe backends — but that's a separate, paid capability, not something open-source Nginx's own max_fails mechanism provides.)
Hands-On Exercises
Write an upstream block named api_pool containing three backend servers on 10.0.0.21:8080, 10.0.0.22:8080, and 10.0.0.23:8080, where the third server should receive twice as much traffic as the other two.
📄 View solutionA team relies entirely on max_fails/fail_timeout and considers their backend pool "actively monitored for health" as a result. Using this chapter's own warning box, explain what's actually true and what's missing from this claim.
📄 View solutionExplain why the keepalive directive inside an upstream block is a genuinely different concept from the client-facing keep-alive settings covered in Web Servers Fundamentals, even though both are called "keep-alive."
📄 View solutionChapter 4 Quick Reference
- upstream {} — names a pool of backend servers, referenced by name inside
proxy_pass - weight — proportional traffic share; max_fails/fail_timeout — reactive failure tracking; backup — last-resort server; down — documented manual exclusion
- keepalive inside
upstream {}reuses Nginx's own connections to the backend — a separate concept from client-facing keep-alive - Open-source Nginx's failure tracking is reactive only — not a substitute for a real, proactive health-check system