Skip to main content
Welcome back. In this lesson we configure an Nginx reverse proxy to act as a load balancer and demonstrate three common balancing methods: round-robin (default), weighted round-robin, and ip_hash (simple sticky sessions). The demo uses two Apache backend servers to show how Nginx can proxy to other web servers (Apache, LiteSpeed, etc.).
A diagram titled "Algorithms: Round Robin" showing an NGINX load balancer sending traffic via a round-robin router to two Apache web servers labeled 1 and 2. The illustration visualizes evenly distributing requests across the web servers.
Round-robin cycles requests evenly across the available backends (request 1 → backend A, request 2 → backend B, request 3 → backend A, and so on). For weighted round-robin you assign weights to each backend so one receives proportionally more requests than the other.
A diagram showing an NGINX load balancer using a weighted round-robin algorithm to distribute traffic to two Apache web servers, with weights 10 and 1.
The ip_hash method pins clients to a backend based on a hash of the client IP — useful for simple session stickiness (for example, shopping carts) when no shared session store is available.
A diagram showing an NGINX load balancer using IP-hash routing to distribute client requests across three web servers. Arrows indicate how the IP-hash maps clients to specific backend servers.

Environment overview

  • One node serves as the Nginx load balancer (nginx).
  • Two nodes run Apache and serve a simple HTML page (node01 and node02).
Validate a backend’s site (example on node01):
Check service status examples:

Restrict direct access to backends (UFW)

Best practice: only allow the load balancer to reach backend HTTP ports. First, discover the load balancer IP (example from ip a on nginx):
On each backend (node01, node02) allow HTTP access only from the load balancer IP:
Confirm UFW rules:
Useful references:

Configure Nginx as a reverse proxy with upstreams

On the load balancer, edit the Nginx site config (example: /etc/nginx/sites-available/apache-app). Confirm the file exists:
Start with an upstream block (the pool of backends) and a server block that proxies requests to it. Example default (round-robin) configuration:
Notes:
  • The example uses IP addresses for the backends (192.230.202.12 for node01 and 192.230.202.3 for node02). You may use DNS names instead.
  • The upstream block above uses Nginx’s default round-robin algorithm.
Test configuration, enable the site and reload Nginx:
Test from the load balancer:

Load balancing methods — quick reference

Weighted round-robin

To bias traffic toward one backend, add weight= to the server entries in the upstream block:
  • With the above weights, roughly 10 requests will go to node01 for every 1 request to node02.
  • Reload Nginx after changes:
Observe behavior in a browser or with repeated curl — the higher-weight backend should serve the majority of requests.

ip_hash (sticky sessions)

Enable basic session stickiness by adding ip_hash to the upstream block. This maps the client IP to a backend and keeps subsequent requests from that IP directed to the same server:
  • Reload Nginx:
  • After enabling ip_hash, the same client IP should consistently be mapped to the same backend. Refreshing from the same client should repeatedly show the same backend serving the request.
ip_hash provides simple sticky sessions by client IP. It is not suitable if clients are behind NAT/proxies that cause many clients to share an IP, and it does not account for backend health checks or capacity — consider more advanced session persistence strategies or a shared session store for production-grade stickiness.

Quick reference — common files & commands

Wrap-up

  • Nginx upstreams default to round-robin load balancing.
  • Use weight= to bias traffic (weighted round-robin).
  • Use ip_hash to pin client IPs to backends for simple session persistence.
  • Always validate changes with nginx -t and gracefully reload Nginx.
  • Restrict backend access (for example with UFW) so only the load balancer can reach backend HTTP ports.
Further reading: That completes this demo.

Watch Video

Practice Lab