Plainnotes

Taking upstreams out: health checks versus balancing

2024-05-27 · 2 min readDeploy

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.