session persistance with IP hash

Robert Paprocki rpaprocki at
Wed Jul 27 20:35:06 UTC 2016


On Wed, Jul 27, 2016 at 1:21 PM, Brian Pugh <project722 at> wrote:

> Running nginx free version 1.10.1-1.el6.ngx.x86_64 on RHEL 6.7. In my conf
> I am using
> http {
>     upstream backend {
>         # Use ip hash for session persistance
>         *ip_hash;*
>         server backend1:80;
>         server backend2:80;
>         server backend3:80;
> }
> My understanding is that the ip_hash directive is responsible for session
> persistence. My questions are:
> 1) How long does it last? For example, if I connect and my ip hash tells
> nginx to connect to backend3, will my source IP be forever tied to backend
> 3?

Yes, sorta. Hashing does not really provide "persistence" in the manner
you're thinking of. An upstream block using hashing will provide a backend
for a given client based on a deterministic hashing algorithm (something
roughly like crc32 of the key, modulo the number of elements in the
upstream group, then accounting for weights). Hash-based balancing is
designed to always provide the same value of a given key, provided that the
weights and status of all backend nodes does not change. If the weights are
changed during runtime, or a node is unreachable, then the hash will return
a different value (and once the node is reachable again, the previous value
will be returned subsequent requests).

2) Is there another way to acheive session persistence other than ip hash
> and other than purchasing plus edition?

There are some third-party modules available, but the quality and stability
of those isn't guaranteed.

3) Is there an ip hash "cache" or something I can clean out periodically to
> force the source IP to get a new hash and therefore a chance to connect to
> a different server?

No, see above. Hashing algorithms are deterministic, given the same number
and weight distribution of backend nodes, you will _always_ get the same
result. That's the point ;) There's no "cache" or pre-determined result for
a given client IP - the upstream is re-calculated with the hashing
algorithm on every request. If Nginx cannot connect to the upstream node
that its hashing algorithm first selects, it will move on to subsequent
nodes in the backend.

If you want very fine-grained/custom/arbitrary load balancing algorithms,
you can write your own in Lua using the ngx+lua module and the
balancer_by_lua directive (
This is not available from vanilla open source Nginx, but it is available
as part of the OpenResty project.

Do also note that in addition to ip_hash method there is a generic hash
method that can take arbitrary keys to generate the hash. This can include
Nginx variables, such as $uri, header values, etc.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the nginx mailing list