October DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsSlow PC?RecommendedPC slow today? Run a repair scan before it gets worseResolve common Windows issues and optimize system performance.Scan NowOctober DealsAmazon USDeal season is back - check today's better picksAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
World desk13 min

How to Set Up NGINX Load Balancing Across Multiple Servers

A practical guide to configuring NGINX load balancing across multiple servers, choosing the right method, handling failures and sessions, and validating the rollout.
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

To load balance several application servers with NGINX, define an upstream group, point a public location block’s proxy_pass at that group, test the configuration, and reload NGINX. Round robin is the default HTTP method; you can switch to least connections or hash-based routing when request duration, caching, or session state requires it.

What NGINX load balancing does

NGINX sits between clients and your application servers as a reverse proxy. Clients connect to one public address. NGINX accepts each request, selects a backend from an upstream group, forwards the request, and returns the selected server’s response.

As an Amazon Associate I earn from qualifying purchases.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The backend machines can run the same application on different hosts or ports. NGINX keeps the backend addresses in one reusable group, so the public server block does not need to know which individual machine should receive a particular request.

  • Availability: traffic can continue when one backend is temporarily unavailable, provided another backend remains healthy.
  • Capacity: requests are distributed among several machines instead of concentrating all work on one server.
  • Operational control: you can drain, isolate, or replace a backend without changing the public hostname.

Load balancing is not the same as replicating application state. If sessions, uploaded files, carts, or other data exist only on one backend, sending the next request to a different server can still break the user experience.

Plan the design before editing NGINX

Identify the protocol

For HTTP or HTTPS applications, configure an http context and use proxy_pass. Raw TCP and UDP services use the stream context instead; the HTTP directives shown in this guide do not apply to those services.

List every backend endpoint

Record the hostname or IP address and listening port for each server. The NGINX host must be able to reach those addresses over the required network path and firewall rules. Use the same application path and response expectations on every member unless you intentionally use weighted capacity.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Choose a state strategy

Decide whether the application uses a shared session store or needs client affinity. Round robin and least connections can send consecutive requests from one client to different machines. A shared session store is usually the more robust solution; ip_hash is an affinity mechanism, not a replacement for shared state.

Define a health endpoint if the application has one

A lightweight endpoint such as /healthz is useful only when the application defines it and its checks represent the dependencies that matter. A process that merely accepts a TCP connection is not proof that the application can serve real requests.

Build the basic HTTP configuration

The following pattern creates a three-server upstream and proxies the public site to it. Replace the example names and port with addresses that resolve from the NGINX host.

http {
    upstream app_backend {
        server app1.example.com:8080;
        server app2.example.com:8080;
        server app3.example.com:8080;
    }

    server {
        listen 80;

        location / {
            proxy_pass http://app_backend;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
        }
    }
}

The upstream name, app_backend, is the value used in proxy_pass. NGINX chooses one server entry for each request. The proxy headers shown are a conventional starting point, but the correct set depends on how the application records client addresses, generates absolute URLs, and detects HTTPS. Validate those requirements before deploying.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Where to put the configuration

Keep the upstream definition in the NGINX configuration’s http context. Put the public server block in the location used by your installation for virtual hosts, then ensure that file is included by the main configuration. Do not place an HTTP upstream inside a server or location block.

Test and apply the configuration safely

  1. Check reachability. From the NGINX host, connect to every backend address and port. Confirm that each machine returns the expected application response and, where applicable, the documented health endpoint.
  2. Test syntax against the intended file. Run nginx -t. Do not reload until NGINX reports that the configuration syntax is valid and the test has loaded the files you edited.
  3. Reload without dropping existing connections. Apply a successful change with nginx -s reload or the reload action provided by your service manager.
  4. Generate repeated requests. Send enough requests to observe more than one backend. Add a temporary backend identifier to responses or inspect access logs while testing so you can see which server answered.
  5. Exercise failure handling. Stop or isolate one backend in a controlled window. Confirm that traffic reaches the remaining servers and that the failed member becomes eligible again after it recovers.
  6. Test application state. Log in, use a cart or other stateful feature, upload a file, and test long-lived connections if those features exist. A successful static-page test does not prove that session handling is correct.
  7. Monitor after rollout. Watch upstream response times, connection failures, and HTTP 5xx responses rather than relying only on NGINX’s successful reload message.

Choose the balancing method for the workload

Method Configuration How selection works Best fit Important limitation
Round robin No method directive; it is the HTTP default Distributes requests across servers, with weights taken into consideration Backends with similar capacity and broadly similar requests It does not account for current connection count or request duration
Least connections least_conn; Chooses the server with the fewest active connections, while considering weights Requests whose processing times vary significantly At low traffic, selection can be less accurate without a shared upstream zone
IP hash ip_hash; Derives a destination from the client IP and keeps that client on the same server while it remains available Legacy applications that require client affinity It is not shared state; clients behind one NAT address can concentrate on one backend
Generic consistent hash hash $request_uri consistent; Uses a chosen key, such as the request URI; consistent hashing limits remapping when members change Cache-like workloads where the same key should usually reach the same server It is only as useful as the key. A URI hash does not preserve login sessions by itself
Least time NGINX Plus HTTP method Considers latency and active connections Commercial deployments that need latency-aware selection It is not an Open Source HTTP method
Random NGINX Plus method Selects randomly from the upstream set, with the Plus method set Specific Plus designs that benefit from randomized selection Availability depends on the NGINX edition

Round robin for equivalent servers

With no method directive, NGINX uses round robin for HTTP. If every backend has similar resources and requests have similar cost, this is the simplest starting point. It is also easy to reason about during an incident because each member receives a predictable share over many requests.

Weights for unequal capacity

Add a weight parameter to a backend when one machine should receive a larger or smaller share. For example:

upstream app_backend {
    server app1.example.com:8080 weight=3;
    server app2.example.com:8080 weight=1;
}

The values express relative preference, not a guaranteed percentage for a short burst. Actual distribution is affected by request timing, failures, keepalive behavior, and the selected method.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Least connections for uneven request duration

Enable least_conn; when a request can occupy a connection for a long or unpredictable time. NGINX then favors the member with fewer active connections, while still considering configured weights. At low load, each worker’s local view can make this decision less precise; a shared upstream zone coordinates the relevant state.

IP hash when affinity is unavoidable

Place ip_hash; in the upstream block when an application expects a client to return to the same backend. The mapping changes when that server is unavailable. Because the key is the client IP, many users sharing a proxy or NAT address may be assigned together, and users whose IP changes will not retain affinity.

Consistent hashing for cache-oriented keys

Use hash $request_uri consistent; when the request URI is the meaningful key, such as a cache partition. The consistent option reduces the number of keys remapped when servers are added or removed. Choose a different variable if the URI is not the data’s natural partition key.

Use weights and methods in a complete upstream

Only one primary balancing method should be selected for an upstream. The following examples show alternatives; do not paste all method directives into the same group.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
upstream app_least_conn {
    least_conn;
    server app1.example.com:8080 weight=2;
    server app2.example.com:8080 weight=1;
}

upstream app_by_uri {
    hash $request_uri consistent;
    server app1.example.com:8080;
    server app2.example.com:8080;
    server app3.example.com:8080;
}

Changing the method changes traffic behavior immediately after the configuration is reloaded. Re-test login flows, cache hit behavior, and backend saturation whenever you make that change.

Understand passive and active health checks

Passive failure handling in Open Source and Plus

Open-source NGINX and NGINX Plus both observe live proxied transactions. When a backend repeatedly fails according to its configured failure parameters, NGINX can mark it unavailable and stop sending requests to it temporarily. This is passive health behavior: a real client request reveals the failure.

Passive handling is useful for connection refusals, timeouts, and failed responses encountered during normal traffic. It cannot detect every application problem before a user request arrives, and an endpoint that accepts connections while its database is down may still appear healthy unless the request exposes that dependency.

Periodic active checks in NGINX Plus

NGINX Plus adds periodic active HTTP checks. NGINX Plus sends a health-check request, evaluates the response, and can remove a member before ordinary traffic discovers the failure. The commercial health-check module requires the upstream group to reside in shared memory.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Use a dedicated endpoint only when the application defines its contract. Decide whether the check should verify dependencies such as a database, queue, or object store; a deep check may provide better protection but can also create load or mark every backend unhealthy when a shared dependency fails.

Recovery behavior

When a failed server recovers, NGINX can make it eligible again according to the configured failure and recovery settings. Test both sides of the event: confirm that requests leave the failed member and that traffic returns in the intended way after recovery. Do not assume that a process restart alone proves the application is ready.

Share upstream state between worker processes

An upstream zone places the server-group configuration and related counters in shared memory so NGINX worker processes coordinate their view. Without a zone, each worker keeps its own copy.

upstream app_backend {
    zone app_backend 64k;
    server app1.example.com:8080;
    server app2.example.com:8080;
    server app3.example.com:8080;
}

A shared zone matters when least-connections decisions need a consistent view at low load. It also enables dynamic upstream configuration scenarios supported by the relevant NGINX edition and modules. The memory size is a configuration choice: allocate enough for the group and its state, and verify the syntax and edition-specific behavior in the documentation for your deployment.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Keep sessions and application data consistent

Preferred approach: externalize shared state

Store sessions in a shared session service or database, and place user-uploaded files and other durable data in storage visible to every backend. Then any backend can serve the next request, allowing round robin or least connections to work without relying on a particular machine.

Fallback approach: client affinity

If the application cannot yet share state, ip_hash can keep a client on one available server. Treat this as a compatibility measure. It does not copy sessions between machines, does not survive every network change, and can create uneven load when many users appear under one source address.

NGINX Plus persistence

NGINX Plus documents additional sticky-session persistence capabilities. If you depend on those features, verify the exact persistence mode, edition, and failure behavior for your release rather than assuming that IP-based affinity provides the same result.

Load balance TCP and UDP services with the stream context

For databases, message brokers, game protocols, or other raw TCP and UDP services, define an upstream under stream and configure a stream proxy. Do not use an HTTP location block for these connections.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
stream {
    upstream tcp_backend {
        server db1.example.com:5432;
        server db2.example.com:5432;
    }

    server {
        listen 5432;
        proxy_pass tcp_backend;
    }
}

Weighted round robin is the default stream method. NGINX also documents least connections, least time, and hash selection for stream upstreams. Stream balancing does not provide HTTP concepts such as paths, HTTP status checks, or application headers, so health and observability must match the protocol you are proxying.

Operational rollout checklist

  • Every backend address and port is reachable from the NGINX host.
  • Each backend serves the expected response, not merely an open socket.
  • The upstream method matches the workload: even capacity, active-connection pressure, latency, cache key, or affinity.
  • Session storage, uploads, and other state are shared or an explicit affinity strategy is documented.
  • The configuration passes nginx -t before reload.
  • Repeated requests and access logs show traffic reaching all intended members.
  • A controlled backend outage demonstrates the configured passive or active health behavior.
  • Recovery is tested, including whether a returning backend should receive traffic immediately or gradually.
  • Dashboards or alerts cover upstream response time, connection failures, and 5xx responses.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Troubleshoot common symptoms

All requests reach one backend

Check whether only one member is reachable, whether the others are marked unavailable, or whether an affinity method is in use. Inspect the resolved addresses and NGINX error log, then test each backend directly from the proxy host.

Users are logged out between requests

The requests are probably reaching different servers whose sessions are local. Move sessions to shared storage, or use a documented affinity strategy as an interim measure. Confirm the result with a real login flow rather than a static request.

Least connections appears uneven

Check for unequal weights, long-lived connections, and low request volume. Without a shared upstream zone, workers have separate views, which can reduce accuracy at low load. A connection count is not the same as CPU utilization or request latency.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

A backend is marked down even though its port is open

TCP acceptance only proves that a process is listening. Inspect the proxied response, timeout behavior, and application dependencies. If active checks are configured, verify the check path and expected status; if only passive handling is available, generate a representative request and inspect the failure recorded by NGINX.

Adding a server causes cache misses

A non-consistent hash can remap many keys when membership changes. For cache-like routing, use a suitable key with hash ... consistent and plan membership changes as cache events. Hashing does not solve session storage or data replication.

Open Source or NGINX Plus?

Capability NGINX Open Source NGINX Plus
HTTP round robin, weights, least connections, IP hash, and generic hash Available Available
Passive failure handling from live transactions Available Available
Periodic active HTTP health checks Not provided by the commercial health-check module Available
Least-time HTTP method Not available Available
Random balancing method Not part of the Open Source method set Available
Additional documented session persistence Not available as the Plus feature Available
Dynamic upstream behavior Depends on the modules and configuration model in use Supported capabilities include commercial dynamic management

Choose the edition based on the operational feature you actually need. Open Source is sufficient for static upstream groups, passive failure handling, and the standard balancing methods. NGINX Plus becomes relevant when periodic active checks, documented sticky persistence, latency-aware selection, or commercial dynamic upstream management justify the additional edition.

Design patterns you can apply

Three equivalent web servers

Use a plain upstream with round robin. Keep sessions and files shared, test every member, and monitor response times. This is the least complex design when requests are comparable.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Mixed-capacity servers

Use round robin with relative weights, or least connections with weights when request duration varies. Revisit the weights after hardware or workload changes; they express intended share, not measured capacity.

Cache partitioning

Use consistent hashing on the cache key, such as a normalized URI, when keeping a key on one member reduces duplicate cache fills. Plan for remapping during membership changes and keep authoritative data outside the cache.

Legacy local-session application

Use IP affinity only when migrating to shared sessions is not immediately possible. Document the NAT and mobile-network drawbacks, and schedule a state-sharing fix so that scaling does not depend on client address stability.

Latency-sensitive commercial deployment

If measured latency should influence selection and the deployment runs NGINX Plus, evaluate the least-time method and active checks together. Define the health endpoint and failure policy first; a faster but functionally broken backend is not a successful selection.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

What to monitor after go-live

Monitor each upstream member separately as well as the public endpoint. Useful signals include active connections, upstream response time, connection failures, timeout counts, HTTP 5xx responses, and the number of members considered unavailable. Compare those signals with application metrics such as request duration, database errors, queue depth, and saturation.

Alert on loss of redundancy before total outage: a service with one remaining backend may still answer successfully while having no tolerance for the next failure. During deployments, watch whether a newly started member receives requests before its caches, migrations, or dependencies are ready.

Key decisions at a glance

Question Use this direction
Are all backends similar and requests comparable? Start with HTTP round robin.
Do request durations vary widely? Consider least_conn, with a shared zone when appropriate.
Must a client return to one machine? Use ip_hash only when shared state is not practical, and document its limits.
Is the workload keyed like a cache? Use a suitable key with consistent hashing.
Do you need checks before user traffic discovers failure? Use NGINX Plus active HTTP checks and a meaningful health endpoint.
Is the service TCP or UDP? Configure the stream context, not HTTP proxying.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More from the Wire

  1. World desk4 min
    How to Spot an AI Voice Scam Before Sending MoneyDon’t rely on how a caller sounds. Pause, call back through a known number, and verify the emergency with another trusted person before sending money.
  2. Mountain View desk4 min
    Google’s SynthID Detector: How to Check AI-Generated Images, Video and AudioGoogle’s SynthID Detector looks for an embedded watermark in supported images, video and audio. Here is what its results do—and do not—show.
  3. Redmond desk20 min
    How to create a link to File or Folder in Windows 11Windows 11 gives you several ways to point to a file or folder without moving or duplicating it. You can create a desktop shortcut,…
Recommended PC Tool
Recommended PC Tool
PC Slower Than It Used to Be?Free scan - under a minute
Crashes, No Sound, or Screen Glitches?Free driver scan

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.