← Load balancing: traffic and resilience
08 / 8 · 60 MIN

Reload, retirement and change evidence

Demonstrate an applied change without losing in-flight requests and distinguish validation, activation and functional acceptance.

Separate candidate, active process and outcome

The experiment starts with the retirement group pointing only to A. The runner changes the file to B and executes nginx -t with the isolated prefix and configuration. The command exits zero, but the next request still reaches A because the reload signal has not been sent. This observation makes the difference between a valid candidate and an applied change concrete. In a change plan, retain which file was validated, the activation action and evidence that the active process uses the expected target.

Construct a transition observation

Before applying the change, the runner starts a long request that A holds pending through a synchronization event. It then sends HUP only to the master created for this lab and makes new requests until B is observed. At that point it checks that the old request has not finished. Only then does it release A and confirm the old request finishes with 200 and body A. The sequence shows two necessary results: new requests reach the new target and previous work can complete at its original target.

Turn observation into a retirement criterion

For a long report during a weekend window, a green B health check does not by itself authorize stopping A. Identify pending requests, owners and available time. If work does not finish, define who decides to wait, interrupt or reconcile a rerun, considering effects and impact. The lab voluntarily releases one request; it neither tests an infinite request nor establishes a business deadline. It also does not validate draining in HAProxy, Kubernetes or AWS. Each platform needs its own criteria and observations for the actual transition.

Describe a negative validation accurately

The last candidate adds a nonexistent directive. nginx -t fails and the runner sends no HUP; a new request still receives B. The result proves that validation prevented an activation attempt in the procedure used. It does not prove automatic rollback of an executed reload because that reload did not occur. The distinction matters in a change report: identify the failed stage and actions actually performed. An accurate description helps the next team reproduce the gate without assuming controls that were never exercised.

Retain a reproduction with explicit scope

Evidence retains the version, build options, configurations, commands, events, logs and runner hash. Acquisition uses the archive at the official HTTPS address; the computed checksum identifies received bytes without independent checksum or PGP signature verification. The local build excludes TLS, rewrite and gzip and was not installed as a system service. The experiment uses ephemeral loopback ports and removes temporary directories. To reproduce in another environment, supply that environment’s binary and build metadata, retaining the separation between configuration and local resources.

Close the change with two operational proofs

In the fictional handover, first present proof of new routing and then completion of the old request. Add the limits: one worker, local HTTP, synthetic servers, no load test or production service. If real acceptance requires authentication, TLS, authorization or report content, add representative checks for those requirements before declaring the change complete. This lesson’s summary is straightforward: validation prepares activation, activation changes the process, and acceptance requires observing the functional outcome and work that still depended on the previous configuration.

# From the project root; provide your local binary and build record
python3 content/labs/lb-upstream/run.py --nginx /path/to/nginx --build-metadata /path/to/build.json --output /tmp/lb-evidence.json
# gracefulReload: beforeSignalBackend A; newConnectionBackend B
# oldRequestPendingWhenBObserved true; oldRequestCompletion A
# invalidCandidate: validation failed, reloadSignalSent false
IN PRACTICE

Fictional case: a report remains on A during the change to B. The team confirms new requests on B, waits for agreed report completion and only then retires A.

Common pitfalls

Treating nginx -t as reload, stopping the old backend after one new 200, or calling a never-applied candidate a rollback.

Related topics: Health checks and readiness · Retries, limits, and client origin · Draining, releases, and operations

Take this idea with you

A change has sufficient evidence only when the new target works and old work received the planned handling. Record executed actions and limits of proof.

Create account

Reference: Controlling NGINX · BigSavant load balancing 2026-09; selected NGINX, HAProxy 3.2, Kubernetes and AWS ALB behavior