Skip to main content
Welcome back. In this lesson we’ll configure an Nginx load balancer and demonstrate three common balancing methods:
  • Round-robin (default)
  • Weighted round-robin
  • ip_hash (simple session affinity / sticky)
We’ll use two Apache backend servers to show that Nginx can balance requests across different web servers.
Diagram showing an NGINX load balancer using a round-robin algorithm to distribute requests evenly to two Apache web servers.
Round-robin alternates requests between backend servers (first request to backend A, second to backend B, etc.). Next we’ll bias traffic toward one backend using weighted round-robin.
A diagram showing an NGINX load balancer using a weighted round-robin algorithm to send traffic to two Apache web servers, one with weight 10 and the other with weight 1. Icons illustrate the load balancer, the weighted round-robin circle, and the web server pool.
Finally, we’ll demonstrate ip_hash, which preserves client affinity by routing a client (based on source IP) to the same backend it reached first — useful for simple session-affinity needs like basic shopping carts when you don’t use centralized session storage.
A diagram showing an NGINX load balancer using an IP-hash algorithm to route incoming requests to three web servers. It illustrates request distribution and session affinity (sticky routing) to specific server instances.

Environment summary

  • root@nginx: Nginx load balancer
  • root@node01: Apache backend 1
  • root@node02: Apache backend 2

Verify backend and balancer services

Check Apache on each backend:
Check Nginx on the load balancer (Nginx should be installed only on the load balancer):

Firewall: allow only the load balancer to reach backend port 80

By design we do not open backend HTTP port 80 to the public. Instead whitelist the load balancer IP on each backend so only the balancer can connect. Find the load balancer IP (example):
Example relevant interface address (trimmed):
  • Load balancer eth0: 192.230.202.10
On each backend add a UFW rule to allow traffic from the load balancer IP to port 80:
Example UFW status after adding the rule:
Only allowing the load balancer to connect to backend port 80 reduces exposure — do not open backend HTTP ports to the public when traffic is meant to be routed through a load balancer.

Nginx configuration: upstream and proxy_pass

On the load balancer, create or edit the site file /etc/nginx/sites-available/apache-app. The two key pieces are:
  • upstream block: defines the pool of backend servers
  • proxy_pass: points the location to the upstream name
Base configuration (simple upstream and proxy_pass):
Notes:
  • The upstream name (apache_example) is referenced in proxy_pass.
  • Upstream entries may be IP addresses or DNS names. Including :80 is explicit but optional for HTTP.
After editing the file:
  1. Test Nginx configuration syntax.
  2. Ensure the site is enabled (create a symlink to /etc/nginx/sites-enabled/ if needed).
  3. Reload Nginx.
Commands:
The ln -s uses a guard to avoid failing if the link already exists. Test locally with curl:
Refreshing the browser or repeating the curl command will show responses alternating between the two backends — the default round-robin behavior.

Weighted round-robin

To bias traffic toward one backend, add a weight for each server in the upstream. For example, to send roughly 10/11 of requests to node01 and 1/11 to node02:
Save, test, and reload:
Now repeated requests will mostly reach the higher-weighted backend and occasionally the lower-weighted one.

ip_hash (session affinity / sticky)

If you need simple session affinity so a client consistently hits the same backend, use ip_hash in the upstream:
Then test and reload:
With ip_hash enabled, routing is based on the client IP. This works for lightweight affinity needs but has important limitations.
ip_hash provides IP-based affinity and is not a substitute for shared session storage. Clients behind the same NAT will share a source IP and be routed to the same backend. If a backend is removed, affinity may be disrupted. For robust session persistence, use a centralized session store or a more advanced load-balancer solution.

Quick reference — balancing methods

Checklist before going to production

  • Validate configuration: sudo nginx -t
  • Reload safely: sudo nginx -s reload
  • Restrict backend access to only the load balancer via firewall rules
  • Consider health checks and monitoring for backends (Nginx Plus or third-party solutions)
  • For robust session persistence, use a centralized session store (Redis, database, etc.)
That completes this lesson on configuring an Nginx load balancer with round-robin, weighted round-robin, and ip_hash session affinity.

Watch Video

Practice Lab