Marcio Cunha

How to configure load balancing in Nginx

Learn how to distribute web traffic across multiple backend servers using Nginx to ensure high availability and prevent downtime.

Marcio Cunha•5 min
Also available in:PortuguêsEspañol
Summary
  • Nginx acts as an intelligent router that splits incoming web requests among several background computers.
  • Algorithms like Round Robin and Least Connections prevent any single server from becoming overwhelmed.
  • Automatic health checks take failed servers out of rotation, keeping the website online without manual intervention.
  • Proper session persistence prevents issues like emptied shopping carts in online stores and lost login states.
  • Combining Nginx with other networking utilities greatly improves the overall resilience of corporate infrastructure.

What is Nginx load balancing and why use it

When a website or application starts receiving a very high volume of visits, a single computer server can no longer handle the load. This is where load balancing comes in, working basically like a bank queue guided by an intelligent attendant: it takes everyone arriving and distributes them evenly among several open cashiers behind the scenes. In practice, this means that if one computer fails, the others keep responding, ensuring the service stays online for end users. Nginx, known for being an extremely fast and lightweight program for handling web connections, plays this maestro role with great efficiency and low memory consumption.

Before diving into setup, remember that managing network traffic requires understanding your systems' behavior, something as critical as analyzing packets with tools like diagnosing broadcast loops in the network with Wireshark. When we configure Nginx to split this load, we create the concept of a server group, also called an 'upstream'. This group gathers the IP addresses or domain names of the internal computers that actually process the web pages, while Nginx sits on the front line receiving raw internet traffic through standard ports 80 and 443.

Setting up the basic upstream block

The first practical step in configuring Nginx to split traffic is declaring which servers will be part of the backend. To do this, we open Nginx's main configuration file, usually located at /etc/nginx/nginx.conf or inside a specific file within the sites-available directory. We use the upstream keyword to name our group and list the IP addresses or domain names of the internal servers that will process client requests.

In practice, the initial configuration looks like creating a service desk list. Here is a functional example of how to declare this group and point your virtual server to it:

http {
upstream my_backend_servers {
server 192.168.1.51:8080;
server 192.168.1.52:8080;
server 192.168.1.53:8080;
}

server {
listen 80;
server_name my-system.com;

location / {
proxy_pass http://my_backend_servers;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
}

In this code snippet, the proxy_pass directive is responsible for forwarding the request received by Nginx to one of the three servers listed in the upstream block. The extra headers help the internal server know the real IP of whoever is accessing the site, preventing it from thinking all requests come from the load balancer itself.

Choosing the ideal distribution algorithm

By default, when you specify no additional rules, Nginx uses a distribution method called 'Round Robin'. It works in a purely rotating fashion: the first request goes to server A, the second to B, the third to C, and then the cycle restarts. Although simple and effective when all backend computers have exact processing capacities, this method can cause bottlenecks if one server is older or weaker than the others.

For scenarios where equipment has varying power, we can change behavior by switching the choice algorithm. The 'least_conn' method, for instance, always sends the new request to the server with the lowest number of active connections at that exact second. Another very useful alternative is adding weights to servers, allowing a more powerful computer to receive double or triple the accesses compared to a more modest machine, balancing the hardware's physical effort.

Ensuring high availability with health checks

Imagine one of your backend servers suffers a power outage or runs out of RAM. If Nginx keeps sending clients to it, those people will receive an annoying page-not-found error message. To prevent this type of operational failure, we need to configure fault tolerance mechanisms that detect when a server dies and automatically remove it from the routing path.

In commercial versions of Nginx, advanced tools exist for this, but even in the free open-source version we can use basic failure control parameters like max_fails and fail_timeout. They tell Nginx: 'if this server fails to respond twice within a ten-second window, pretend it does not exist for thirty seconds'. To keep infrastructure even safer against external attacks or intrusion attempts, you can complement this protection by applying security rules such as how to block malicious IPs in Nginx with Fail2Ban, ensuring malicious traffic is cut off before reaching your backends.

Maintaining user sessions with IP Hash

A classic challenge when distributing traffic across multiple servers is the lost session problem. Think of an online store: the customer puts an item in the cart on server A, but on the next page Nginx redirects them to server B. If server B does not know what was in server A's cart, the purchase is emptied and the customer gets frustrated. To solve this, we use strategies so the same visitor is always served by the same backend server.

The most straightforward way to do this in Nginx without using complex external databases is using the ip_hash algorithm inside the upstream block. Nginx performs a mathematical calculation using the IP address of the incoming visitor and guarantees that specific IP always hits the same backend machine. If that machine goes down, the system redirects the user to another available server, minimizing the impact of the crash on the final consumer.

Final considerations

Configuring load balancing in Nginx transforms fragile infrastructure into a robust environment capable of absorbing traffic spikes without losing stability. We saw that the process ranges from creating upstream blocks to choosing algorithms suited to your hardware reality, plus the vital care given to session persistence and server health checks.

Mastering these routing and reverse proxy tools is a definite step for any professional wanting to scale web applications safely and predictably. When planning your network architecture, always remember to test simulated failures in a staging environment before going live, ensuring the system recovers on its own from any everyday unexpected event.