How to Configure Load Balancing with Sticky Sessions in Easegress

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, with sticky session support handled by HTTPSessionSticker in 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).

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

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 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 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:

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 (GeneralLoadBalancer) and 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

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.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →