# HAProxy Session Persistence v.s. Drain State

**URL:** <https://discourse.haproxy.org/t/haproxy-session-persistence-v-s-drain-state/7705>\
**Category:** Help!\
**Created:** [June 1, 2022, 12:03am UTC](https://discourse.haproxy.org/t/haproxy-session-persistence-v-s-drain-state/7705 "2022-06-01T00:03:53Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![pieterbenjamin](https://avatars.discourse-cdn.com/v4/letter/p/7cd45c/32.png) [@pieterbenjamin](https://discourse.haproxy.org/u/pieterbenjamin)\
**Post date:** [June 1, 2022, 12:03am UTC](https://discourse.haproxy.org/t/haproxy-session-persistence-v-s-drain-state/7705/1 "2022-06-01T00:03:53Z")

</div>

Hello HAProxy community!

I am seeking clarification on documentation concerning [session persistence](https://www.haproxy.com/documentation/hapee/latest/load-balancing/session-persistence/) and the [drain state](https://www.haproxy.com/documentation/hapee/latest/api/runtime-api/set-server/#change-a-server-s-state).

In a few words,

**can I leverage cookie/ip “session persistence” (linked above) to route “new” requests to a server in drain state?**

In more words,

Consider I have two backend servers (`backend_a` and `backend_b`) load balanced by an HAProxy instance. Now let my client perform the following three requests:

1. Initial sign in/authentication (in the background, we were load-balanced onto `backend_a`)
2. Load resource (`table_t`) onto the current server servicing us (in this case `backend_a`). This resource comes from another downstream component irrelevant to this question.
3. Stream the contents of `table_t` from the same server we loaded the table onto (`backend_a`) to somewhere on our client.

For obvious reasons, these three requests need to occur in order on the same backend server (`backend_a`). For simplicity’s sake, let me say that we load balance based on a hash of the username. Our backend config then looks like

```auto
backend server
  balance hdr(username-hash)
  hash-type consistent
  ... 
  option redispatch

```

**If I decide to drain** `backend_a` **using the runtime API after request 2 is sent AND BEFORE REQUEST 3 IS SENT, is there any way to get request 3 onto** `backend_a`? From what I have found ([Management | Enable/Disable Servers | HAProxy Enterprise 2.8r1](https://www.haproxy.com/documentation/hapee/latest/management/enable-disable-servers/)), the drain state will

> set server state to DRAIN (remove from load-balancing, but remain available for health checks and persistent connections)

But, I’m not sure if cookie/IP persistence constitutes a “persistent connection”.

- This forum post supports my hope that the “persistent connections” include the stick-table and not just the literal TCP connections - [sticky-sessions-and-drain-not-working-together](https://discourse.haproxy.org/t/sticky-sessions-and-drain-not-working-together/6876)

> [@Sticky sessions and drain not working together](https://discourse.haproxy.org/t/sticky-sessions-and-drain-not-working-together/6876/2):
>
> Setting the mode to “drain” only removes the server from load balancing but still allows it to be checked and to accept new persistent connections. Changes are propagated to tracking servers if any.

- I may need to remove `option redispatch` - [Sticky Session/ Session Persistence](https://discourse.haproxy.org/t/sticky-session-session-persistence/1976)
- Without `redispatch`, we will stay bound to a server even if the server breaks - [option redispatch](https://cbonte.github.io/haproxy-dconv/1.7/configuration.html#4.2-no%20option%20redispatch)

TL;DR will cookie or ip based “persistence” allow _new requests_ (without an existing TCP connection) to connect to a server in the drain state while using `option redispatch`?

---

<div class="post-metadata">

**Author:** ![Baptiste](https://avatars.discourse-cdn.com/v4/letter/b/cab0a1/32.png) [@Baptiste](https://discourse.haproxy.org/u/Baptiste)\
**Post date:** [June 1, 2022, 5:41am UTC](https://discourse.haproxy.org/t/haproxy-session-persistence-v-s-drain-state/7705/2 "2022-06-01T05:41:42Z")

</div>

Hi,  
I think you want to read this blog article, it’s old, but its content is still pretty accurate:

> **[Load Balancing, Affinity, Persistence, Sticky Sessions: What You Need to Know...](https://www.haproxy.com/fr/blog/load-balancing-affinity-persistence-sticky-sessions-what-you-need-to-know/)**
>
> To ensure high availability and performance of Web applications, it is now common to use a load-balancer. While some people uses layer 4 load-balancers, it can be sometime recommended to use layer 7 load-balancers to be more efficient with HTTP...

Using a “deterministic” LB algorithm (like the hash you mentionned) does not work with “drain” mode. That said, if you enable cookie or stick table based persistence, then the following happens:

- if a new user comes in, he will be routed to any server in the backend but the ones in DRAIN mode
- if a user comes with a persistence information pointing to a server in DRAIN mode, then HAProxy will route this user to the server (unless the server is set as DOWN by the health check of course)

It’s not a “persistent TCP connection”, it’s more a HTTP based session persistence, so all the traffic from a single user will be routed to a server in drain mode.

Note that the log line from HAProxy will have some very useful persistence flags too.

---

<div class="post-metadata">

**Author:** ![pieterbenjamin](https://avatars.discourse-cdn.com/v4/letter/p/7cd45c/32.png) [@pieterbenjamin](https://discourse.haproxy.org/u/pieterbenjamin)\
**Post date:** [June 2, 2022, 6:35pm UTC](https://discourse.haproxy.org/t/haproxy-session-persistence-v-s-drain-state/7705/3 "2022-06-02T18:35:53Z")

</div>

Thank you so much @Baptiste ! This looks like exactly what I need 🙂
