Product

Product Features How to Compare Docs Screenshots Why

Start here

Getting started Download Guides Frequently asked questions

More

Security Support Roadmap About

Traffic

Sticky sessions

Sending the same visitor back to the same backend every time. The paid nginx has a directive for this. Free nginx does not, so the manager generates the cookie half itself and the result behaves the same way.

lb-01.example.net/lb/pools/2
The sticky sessions and slow start tab on a pool.
The sticky sessions and slow start tab on a pool.

How it is built

Turn on sticky sessions for a pool and the manager writes out two map blocks. One reads the route cookie to decide which upstream to hash on. The other decides whether this client needs a cookie at all. The upstream itself hashes on that value with consistent turned on.

A visitor gets a cookie on their first request and lands on the same backend from then on. The very first request is the exception: there is no cookie yet, so it goes wherever the client address hashes to, and the cookie takes over from the second request onward. The paid nginx behaves the same way for the same reason.

Two things about the cookie that are not obvious

Both of these were wrong in the first version of this feature, and both produced something that looked configured and did the opposite of its name.

The value has to be stable and does not have to mean anything

It is a request id. What makes a client stick is the same string coming back every time, not what the string says. Writing the backend's own address into the cookie seems natural and is actively harmful: the hash of an address does not land on that address, it lands wherever it lands, so the next response writes a different backend into the cookie and the visitor walks around the pool one request at a time.

It must only be set when the client does not already have one

Setting it on every response overwrites the route they were given, every time, which undoes the whole thing. That is what the second map block is for.

Why consistent hashing matters here

Without it, taking one backend out of a pool of four moves roughly everybody to a different server, which for a sticky pool means logging out roughly everybody. With it, only the visitors who were on that one backend move.

The real fix is to not need this

Sticky sessions are a workaround for applications that keep session state in local memory, and they carry a real cost: one backend dying logs out everybody who was on it. Put sessions in redis or your database and any backend can serve any visitor. Then you can take servers out whenever you want and never think about this page again.

How we score ourselves on this

Three stars out of five on the comparison page, against five for NGINX Plus, Kemp and HAProxy ALOHA. It works and it is genuinely useful, and it is a config generation trick rather than something the proxy does natively, so the first request is not sticky and a reload is involved when the pool changes. Saying that plainly is more useful than claiming parity.

Common questions

Is the first request sticky?

No, and it is not sticky in NGINX Plus either. There is no cookie yet, so the first request goes wherever the client address hashes to. The cookie takes over from the second request.

What happens when a backend goes down?

Visitors who were pinned to it move to another backend and, if your application keeps sessions in local memory, they are logged out. Everybody else stays where they were, because the hash is consistent.

Can I choose the cookie name?

Yes. The default is fine for most people. Change it if you already have a cookie by that name.

Step by step instructions

The how to section has searchable, task shaped answers. Search it for sticky.

Related features

Two fresh servers is all it takes

Ubuntu 22.04 or newer, root access, and about twenty minutes. The installer does the rest and it is safe to run twice.