Taking upstreams out: health checks versus balancing
One upstream dies and nginx keeps sending traffic until max_fails failures accumulate. The defaults are max_fails=1 and fail_timeout=10s: after one failure, no attempts for ten seconds. Fine for low traffic, harmful at high volume.
Active health checks require the commercial build or OpenResty; open source relies on passive marking:
upstream app {
server 10.0.1.5:8080 max_fails=3 fail_timeout=30s;
server 10.0.1.6:8080 max_fails=3 fail_timeout=30s;
}
fail_timeout serves as both the removal duration and the counting window, which is easy to misread.
And make the health endpoint check dependencies. If the database is unreachable, /healthz should return 503 so nginx removes the node. A check that only proves the process exists proves nothing.