ALB Sticky Sessions: Duration-Based vs Application-Based Cookies and When to Avoid Them

3 min readCloud Infrastructure

Sticky sessions bind a client to a specific target for the duration of their session. ALB offers two mechanisms: duration-based (ALB-managed cookie) and application-based (your app sets the cookie). Both work, but stickiness hides state management problems — stateless backends almost always serve you better.

awsload-balanceralbsessions

What sticky sessions do and why you'd want them

By default, ALB distributes each request to a healthy target using the configured load balancing algorithm (round-robin or least outstanding requests). The same client's second request can go to a completely different target than the first.

For stateless backends, this is fine — any target can handle any request. For stateful backends that store session data in local memory (not in a shared database or cache), the client must return to the same target to access their session state.

Sticky sessions instruct ALB to route a client's subsequent requests to the same target they initially connected to, using a cookie to identify the target.

Two stickiness mechanisms

ConceptAWS ALB

Duration-based stickiness: ALB creates and manages a cookie (AWSALB) that maps the client to a target. Your application doesn't need to do anything. Application-based stickiness: your application creates a custom cookie that ALB reads to identify the target affinity. Gives you more control over when stickiness starts and how long it lasts.

Prerequisites

  • HTTP cookies
  • ALB target groups
  • load balancing algorithms

Key Points

  • Duration-based: ALB sets AWSALB cookie (or AWSALBAPP for CORS). Cookie lifetime = stickiness duration.
  • Application-based: app sets a cookie; ALB reads it to route to the same target. ALB also sets AWSALBAPP as a routing reference.
  • If the sticky target becomes unhealthy, ALB routes to a new target and issues a new stickiness cookie.
  • Clients without cookie support (many API clients, health checkers) don't get sticky behavior.

Duration-based stickiness: ALB manages the cookie

The simplest option. ALB creates the AWSALB cookie on the first request and uses it to route subsequent requests to the same target:

resource "aws_lb_target_group" "app" {
  name     = "app"
  port     = 8080
  protocol = "HTTP"
  vpc_id   = aws_vpc.main.id

  stickiness {
    type            = "lb_cookie"       # duration-based (ALB cookie)
    cookie_duration = 86400             # seconds (1 day); 1-604800 range
    enabled         = true
  }
}

The client receives Set-Cookie: AWSALB=<hash>; ... on the first response. ALB reads this cookie on subsequent requests to route back to the same target. The hash encodes the target identity — clients cannot forge it.

Application-based stickiness: app controls the cookie

Your application sets a named cookie when a session begins. ALB reads that cookie to determine which target to route to:

stickiness {
  type            = "app_cookie"
  cookie_name     = "SESSIONID"       # the cookie your app sets
  cookie_duration = 3600              # ALB's stickiness duration (separate from app cookie TTL)
  enabled         = true
}

When ALB sees a request with Cookie: SESSIONID=abc123, it routes to the target that handled the request where SESSIONID was first set. ALB also issues its own AWSALBAPP cookie as a routing reference.

Application-based stickiness is appropriate when your application already manages session cookies and you want stickiness to align with your application's session lifecycle rather than a fixed time duration.

When stickiness creates problems

Uneven load distribution: if some clients have long sessions, targets get stuck with them. A target serving 10 long-running sessions can be at 100% CPU while others are idle. The load balancer appears to be working but isn't actually balancing.

Target replacement complications: during rolling deployments, new tasks replace old ones. Clients stuck to old tasks keep hitting them until the task is drained and deregistered. Reducing deregistration_delay helps, but clients may experience session loss when their sticky target is removed.

False sense of statefulness: stickiness works until it doesn't — if a target fails, the client gets a new target and loses their local session state. Stickiness is not a session persistence guarantee.

💡The right architecture: stateless backends

The alternative to sticky sessions is moving session state out of the application process:

Redis (ElastiCache): store session data keyed by session ID. Any backend instance can access any session. Scale horizontally without session loss.

import redis
import uuid
import json

redis_client = redis.Redis(host=os.environ['REDIS_HOST'], port=6379)

def create_session(user_data: dict) -> str:
    session_id = str(uuid.uuid4())
    redis_client.setex(
        f"session:{session_id}",
        3600,   # TTL: 1 hour
        json.dumps(user_data)
    )
    return session_id

def get_session(session_id: str) -> dict:
    data = redis_client.get(f"session:{session_id}")
    if data:
        return json.loads(data)
    return None

DynamoDB: serverless session storage with built-in TTL. Good for Lambda backends where in-memory state doesn't persist between invocations.

JWTs: encode session state in a signed token. No server-side storage. Backend is fully stateless. Downside: tokens can't be revoked until expiry.

With externalized session state, any ALB target can handle any request — stickiness becomes unnecessary, load distribution is even, and deployments are simpler.

Stickiness for specific use cases that genuinely need it

Some legitimate uses for sticky sessions:

WebSocket connections: WebSocket connections are persistent — once established, requests on the same connection must stay with the same backend. ALB handles WebSocket connections correctly, and stickiness ensures the connection upgrade and subsequent messages reach the same target.

Long-running computation: if a client initiates a multi-step workflow with intermediate state on the backend (e.g., multi-step file upload with server-side state), stickiness ensures steps reach the same process.

Canary/weighted deployments: weighted forwarding with stickiness ensures a client gets a consistent experience from one target group (v1 or v2), not a mix.

For most standard web application requests, if you need sticky sessions, that's a signal to move state to Redis or a database rather than adding stickiness to the load balancer.

An ALB has 3 targets with duration-based stickiness (1-hour cookie). After a deployment replaces all 3 targets with new instances, some clients report being logged out. What is happening?

easy

The old targets are deregistered and new targets are registered. The application stores session state in the process memory of each target. The ALB stickiness cookie (AWSALB) still exists in the client's browser.

  • AThe AWSALB cookie expires after deployment
    Incorrect.The AWSALB cookie is set by ALB with the configured duration. Deployment doesn't cause the cookie to expire.
  • BAfter deregistration, the sticky target no longer exists — ALB routes to a new target, which has no session state for the client. The application treats this as a new, unauthenticated session
    Correct!Stickiness binds the client to a specific target instance. When all old targets are replaced, the AWSALB cookie references targets that no longer exist. ALB selects a new target and updates the stickiness cookie. The new target has no session data (it only exists in memory on the old, now-terminated target). The application creates a new session, and the client appears logged out. This is the fundamental problem with in-process session state — it doesn't survive instance replacement. Fix: store sessions in Redis or another external store.
  • CThe deployment caused a brief period of no healthy targets, timing out existing sessions
    Incorrect.This could cause request timeouts, not session loss. The session loss happens because session state is local to each target instance.
  • DAWSALB cookies are signed with a key that changes on deployment
    Incorrect.AWSALB cookie values are generated by ALB, not tied to application deployment. ALB manages the cookie independently.

Hint:What happens to the session data stored in process memory when that process (target instance) is terminated?