# How to Configure Load Balancing with Sticky Sessions in Easegress

> Learn to configure sticky sessions in Easegress load balancing using CookieConsistentHash DurationBased or ApplicationBased modes for robust session management. Maximize user experience today.

- Repository: [MegaEase/easegress](https://github.com/megaease/easegress)
- Tags: how-to-guide
- Published: 2026-03-07

---

**Configure sticky sessions in Easegress by setting the `stickySession` field inside your proxy's `loadBalance` configuration, choosing from three modes: `CookieConsistentHash`, `DurationBased`, or `ApplicationBased`.**

Easegress implements sophisticated load balancing through the `GeneralLoadBalancer` in [`pkg/filters/proxies/loadbalance.go`](https://github.com/megaease/easegress/blob/main/pkg/filters/proxies/loadbalance.go), with sticky session support handled by `HTTPSessionSticker` in [`pkg/filters/proxies/stickysession.go`](https://github.com/megaease/easegress/blob/main/pkg/filters/proxies/stickysession.go). This architecture allows you to maintain client-server affinity using cookie-based session persistence, ensuring subsequent requests from the same client reach the same backend server.

## Sticky Session Modes in Easegress

Easegress supports three distinct sticky session modes, each suited for different application architectures. The mode is configured via the `mode` field in `StickySessionSpec`.

### CookieConsistentHash

This mode uses an existing application cookie as the hash key. Easegress reads the value of `appCookieName` from the request and uses consistent hashing to select a backend server. This is ideal when your application already sets a session ID or user identifier cookie.

### DurationBased

In this mode, Easegress generates its own load balancer cookie (`lbCookieName`, defaulting to `EG_SESSION`) that encodes a signed server ID and expiration timestamp. The cookie persists for `lbCookieExpire` (default `2h`). This mode is best for stateful applications that need temporary session affinity without modifying application code.

### ApplicationBased

Similar to `DurationBased`, but the LB cookie is only set if the upstream response already contains the application cookie specified in `appCookieName`. This enables "lazy" session affinity—stickiness only activates after the application has established a session, conserving resources for stateless requests.

## Configuration Syntax and Examples

Sticky sessions are configured within the `loadBalance` block of a **Proxy** or **GRPCProxy** filter. The relevant schema is defined in `proxy.StickySessionSpec` (documented in [`docs/07.Reference/7.02.Filters.md`](https://github.com/megaease/easegress/blob/main/docs/07.Reference/7.02.Filters.md)).

### Key Configuration Fields

| Field | Type | Description |
|-------|------|-------------|
| `mode` | string | Required. One of `CookieConsistentHash`, `DurationBased`, or `ApplicationBased`. |
| `appCookieName` | string | Name of the application cookie used in `CookieConsistentHash` and `ApplicationBased` modes. |
| `lbCookieName` | string | Name of the LB-generated cookie. Defaults to `EG_SESSION`. |
| `lbCookieExpire` | string | Duration string (e.g., `"2h"`, `"30m"`). Defaults to `2h`. |

### YAML Configuration Example

```yaml
apiVersion: easegress.megaease.com/v2
kind: Proxy
metadata:
  name: sticky-proxy
spec:
  serverPool:
    servers:
      - url: http://10.0.0.1:8080
      - url: http://10.0.0.2:8080
      - url: http://10.0.0.3:8080
    loadBalance:
      policy: roundRobin
      stickySession:
        mode: DurationBased
        lbCookieName: SESSION_ID
        lbCookieExpire: 1h

```

In this example, Easegress first checks for the `SESSION_ID` cookie. If present and valid, the request routes to the encoded backend server. Otherwise, the round-robin policy selects a server, and Easegress sets the `SESSION_ID` cookie with a 1-hour expiration.

## How Sticky Sessions Work Internally

Understanding the internal flow helps debug sticky session behavior and implement custom extensions.

### The Load Balancing Flow

The `GeneralLoadBalancer` in [`pkg/filters/proxies/loadbalance.go`](https://github.com/megaease/easegress/blob/main/pkg/filters/proxies/loadbalance.go) orchestrates the process:

1. **Initialization**: In `GeneralLoadBalancer.Init` (lines 99-125), the system creates the load balancing policy based on `LoadBalanceSpec.Policy`. If a `StickySession` spec exists, it invokes the session sticker factory to create a `SessionSticker` instance (line 27), stored in `glb.ss`.

2. **Server Selection**: `GeneralLoadBalancer.ChooseServer` first queries the session sticker via `glb.ss.GetServer`. If the sticker returns a valid server (e.g., decoded from a cookie), that server is used immediately. Otherwise, the configured policy selects a server (lines 13-20).

3. **Response Processing**: After the upstream response, `GeneralLoadBalancer.ReturnServer` calls `glb.ss.ReturnServer`. This allows the `HTTPSessionSticker` to inspect the response and set the stickiness cookie if needed.

### HTTPSessionSticker Implementation

The `HTTPSessionSticker` in [`pkg/filters/proxies/stickysession.go`](https://github.com/megaease/easegress/blob/main/pkg/filters/proxies/stickysession.go) handles cookie logic:

- **Consistent Hashing**: For `CookieConsistentHash` mode, it builds a consistent hash ring in `UpdateServers` (lines 22-34) using `consistent.New`. It hashes the `appCookieName` value to select a backend.

- **Cookie Validation**: In `getServerByLBCookie` (lines 52-71), it validates the signed cookie using HMAC to prevent tampering. The cookie contains the server ID and expiration timestamp.

- **Cookie Generation**: The `sign` method (lines 93-105) creates a new signed cookie. In `ReturnServer` (lines 15-34), if no valid sticky cookie exists, it generates one using the selected server's ID and the configured expiration duration.

## Programmatic Usage in Go

For developers building custom filters, you can instantiate the load balancer programmatically:

```go
import (
    "github.com/megaease/easegress/pkg/filters/proxies"
    "github.com/megaease/easegress/pkg/filters/proxy"
)

// Define the load balance specification
spec := &proxy.LoadBalanceSpec{
    Policy: "roundRobin",
    StickySession: &proxy.StickySessionSpec{
        Mode:           proxy.StickySessionModeDurationBased,
        LBCookieName:   "MY_SESSION",
        LBCookieExpire: "1h",
    },
}

// Create server list
servers := []*proxy.Server{
    {URL: "http://10.0.0.1:8080"},
    {URL: "http://10.0.0.2:8080"},
}

// Instantiate the load balancer
lb := proxies.NewGeneralLoadBalancer(spec, servers)
lb.Init(
    func(s *proxy.StickySessionSpec) proxies.SessionSticker {
        return proxies.NewHTTPSessionSticker(s)
    },
    nil, // health checker (optional)
    nil, // policy (optional, uses spec.Policy)
)

// Usage in request handling
server := lb.ChooseServer(req)
// ... process request ...
lb.ReturnServer(server, req, resp)

```

This pattern allows custom filters to leverage the same sticky session logic used by the built-in Proxy filter.

## Summary

- **Sticky sessions in Easegress** are configured within the `loadBalance.stickySession` block of a Proxy or GRPCProxy filter, supporting three modes: `CookieConsistentHash`, `DurationBased`, and `ApplicationBased`.

- **Core implementation** resides in [`pkg/filters/proxies/loadbalance.go`](https://github.com/megaease/easegress/blob/main/pkg/filters/proxies/loadbalance.go) (`GeneralLoadBalancer`) and [`pkg/filters/proxies/stickysession.go`](https://github.com/megaease/easegress/blob/main/pkg/filters/proxies/stickysession.go) (`HTTPSessionSticker`), which handle server selection, cookie validation, and consistent hashing.

- **Configuration fields** include `mode`, `appCookieName`, `lbCookieName` (defaults to `EG_SESSION`), and `lbCookieExpire` (defaults to `2h`).

- **Programmatic usage** allows custom filters to instantiate `GeneralLoadBalancer` with a `StickySessionSpec` and a session sticker factory.

## Frequently Asked Questions

### What is the default cookie name for sticky sessions in Easegress?

The default cookie name is **`EG_SESSION`**. You can override this by setting the `lbCookieName` field in your sticky session configuration. This cookie stores a signed server ID and expiration timestamp when using `DurationBased` or `ApplicationBased` modes.

### How does Easegress handle sticky sessions when a backend server goes down?

When a backend server becomes unavailable, the `GeneralLoadBalancer.ChooseServer` method first attempts to retrieve the server from the session sticker. If the sticker returns a server that is no longer in the healthy server pool, the load balancer falls back to the configured load balancing policy (round-robin, random, etc.) to select a new available backend.

### Can I use sticky sessions with gRPC services in Easegress?

Yes, sticky sessions work with the **GRPCProxy** filter using the same configuration syntax as the HTTP Proxy. The `loadBalance.stickySession` block supports identical fields (`mode`, `lbCookieName`, etc.) for gRPC traffic, though cookie-based stickiness is typically relevant when gRPC is transported over HTTP/2 with browser-based clients or specific metadata handling.

### What is the difference between DurationBased and ApplicationBased sticky session modes?

**DurationBased** mode generates a load balancer cookie immediately upon the first request, regardless of whether the application has created a session. **ApplicationBased** mode only sets the LB cookie if the upstream response already contains the application cookie specified in `appCookieName`. Use `ApplicationBased` to conserve resources by only enabling stickiness for clients that have established application sessions, while `DurationBased` provides immediate affinity for all clients.