Implementing a Fastest‑First Load‑Balancing Strategy for NGINX with Lua and OpenResty

This article describes how to create a “fastest‑first” load‑balancing algorithm for NGINX using OpenResty and Lua, including the design principles, modifications to lua‑upstream‑nginx‑module, weight‑adjustment logic, Docker build steps, and practical considerations for handling latency‑based server weighting.

Architect
Architect
Architect
Implementing a Fastest‑First Load‑Balancing Strategy for NGINX with Lua and OpenResty

The author built a custom load‑balancing strategy that always prefers the backend with the shortest response time, using OpenResty (NGINX with many bundled modules) and Lua scripts.

The implementation relies on a Lua module ( dynamic-upstream-weight.lua) and two global key‑value caches to store latency data, as described in the author’s NGINX site configuration.

To enable dynamic weight adjustments, the author forked lua-upstream-nginx-module (commit 6b40d40a4) and added Lua APIs for modifying a server’s weight, effective_weight, and current_weight.

Design principles (four laws) :

Define “fast” by the NGINX variable upstream_response_time; a smaller value indicates a faster server, and assign it a larger weight.

If a server becomes unavailable, lower its weight to a minimal value (e.g., 1) instead of removing it entirely, allowing occasional health checks.

Update weights only when certain triggers occur (e.g., response‑time deviation exceeds a threshold) to avoid excessive re‑weighting.

Avoid getting stuck in a local optimum by ensuring the algorithm can still discover the truly fastest backend.

Implementation details:

Lua code runs in log_by_lua_file to read response times and adjust weights.

The custom directive labor is used in the upstream block to activate the strategy, e.g.:

upstream backend {
labor;
server back1.example.com;
server back2.example.com;
}

Docker build notes:

The author shares a Dockerfile that installs OpenResty dependencies, compiles the modified module, and configures log forwarding to Docker’s stdout/stderr using symbolic links:

RUN ln -sf /dev/stdout ar/loginx/access.log
RUN ln -sf /dev/stderr ar/loginx/error.log

Additional observations include the difficulty of compiling OpenResty locally, the use of a pre‑built compilation environment on a CI platform, and various ways to handle log collection inside containers.

Overall, the article provides a practical guide for developers who need latency‑aware load balancing in NGINX without purchasing NGINX Plus, demonstrating how Lua and OpenResty can extend NGINX’s capabilities.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Backend DevelopmentLuaOpenResty
Architect
Written by

Architect

Professional architect sharing high‑quality architecture insights. Topics include high‑availability, high‑performance, high‑stability architectures, big data, machine learning, Java, system and distributed architecture, AI, and practical large‑scale architecture case studies. Open to ideas‑driven architects who enjoy sharing and learning.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.