Nginx upstream and load balancer

By:    Updated: January 26,2017

Application servers (such as PHP FastCGI ) are quite resource-consuming, especially in terms of CPU. In order to improve the throughput and speed  of servers, you can balance the load across multiple servers with Nginx upstream module.

Nginx running as load balancer with Upstream Module

The Nginx Upstream Module module is used to define groups of servers that can be referenced by the proxy_pass, fastcgi_pass, uwsgi_pass, scgi_pass, and memcached_pass directives. Here, I will use fastcgi_pass.

Nginx upstream and load balancer

Nginx Configuration

The Upstream module allows you to declare named upstream blocks that define server list:

upstream php_server_list {
	server max_fails=3 fail_timeout=30s;
	server weight=5;
	server backup;

server {
    root         /home/webroot/;

    location ~* \.php*$ {
        fastcgi_pass   php_server_list;

In this case, requests via FastCGI will be forwarded to one of the backend servers defined in the upstream block.


How does Nginx decide which backend server is to be employed for each request? And the answer is simple: the default method of the Upstream module is round robin. However, this method is not necessarily the best. Two requests from the same visitor might be processed by two different servers, and that could be a problem for many reasons (for example, when PHP sessions (session.save_handler = files) are stored on the backend server and are not replicated across the other servers. If you mount the session path on every servers with nfs or store sessions in database (or nosql such as redis), you will not have this problem).


To ensure that requests from a same visitor always get processed by the same backend server, I enable the ip_hash option when declaring the upstream block. However, be aware that client IP addresses are sometimes subject to change for various reasons such as dynamic IP refresh, proxy switching, and so forth. Consequently, the ip_hash mechanism cannot fully guarantee that clients will always be guided to the same upstream server. Alternatively, you may force Nginx to select the backend server that currently has the last amount of active connections, through the use of the least_conn directive.

More in Development Center
New on Valinv
Related Articles
Sponsored Links