skip to content

How does session stickiness work on an AWS Application Load Balancer, what are the two types it offers, and what tends to break when a system depends on it?

level: middleimportance: should knowfreq 48%

answer

  1. configured on the target group, not the listener
  2. a cookie carries the target reference
  3. two flavours: load-balancer timer or app session
  4. the pin dies when the target does

basics

~20 s

ALB stickiness is a target group attribute that pins a client to one target using a cookie. Duration-based stickiness uses the load balancer's own AWSALB cookie with a fixed lifetime; application-based stickiness follows a cookie your app names. Both fail when the target goes away.

solid answer

~50 s

Stickiness is configured on the **target group**, not the listener, via `stickiness.enabled` and `stickiness.type`. With `lb_cookie` (duration-based) the ALB issues its own encrypted cookie, `AWSALB`, whose lifetime you set with `stickiness.lb_cookie.duration_seconds`; every request carrying it goes to the same target until it expires. With `app_cookie` you name a cookie your application already sets - a session id, typically - and the ALB issues an `AWSALBAPP` cookie alongside it, so the sticky window matches the application's own session lifetime instead of a wall-clock timer. The cookies are opaque to your code; the ALB encrypts the target reference inside them. What breaks: a target that is deregistered, replaced during a deploy, or fails its health check sends its pinned clients elsewhere and any in-memory session is lost; load skews after a scale-out because existing clients stay put; and non-browser clients that discard cookies never stick at all. Stickiness is a mitigation, not an architecture - externalising session state is the real fix.

go deeper

for a junior

Know that stickiness sends a returning client back to the same target using a cookie, and that it is turned on at the target group level rather than on the listener.

for a middle

Distinguish duration-based (lb_cookie, the ALB's own AWSALB cookie and a fixed timer) from application-based (app_cookie, keyed to a cookie your app names), and explain why the second aligns better with a real session.

for a senior

Show the failure modes you have lived with: skewed load after scale-out, sessions lost on deregistration and deploys, cookie-less clients that never stick, and the migration to an external session store.

for a principal

Take the position: affinity is a bridge, not a design. Decide when the platform tolerates it, what it costs in deploy safety and capacity headroom, and what the exit plan to stateless targets looks like.

## Where it lives and what it does Session affinity on an Application Load Balancer is a property of the **target group**, which surprises people who go looking for it on the listener or the rule. It is switched on with the target group attribute `stickiness.enabled` and shaped by `stickiness.type`, which takes one of two values. **`lb_cookie` - duration-based.** The ALB generates its own cookie named `AWSALB` and sets it on the response. Inside it, encrypted, is a reference to the target that served the request. Any later request presenting that cookie is routed to the same target until the cookie's lifetime expires; the lifetime comes from `stickiness.lb_cookie.duration_seconds` and is a fixed timer measured from issue, not a sliding idle window. Because the ALB owns the cookie, this works without a single line of application code. You may also see a companion `AWSALBCORS` cookie: it carries the same value with `SameSite=None; Secure` so that affinity survives cross-origin requests in browsers that would otherwise drop the plain cookie. **`app_cookie` - application-based.** You tell the target group the name of a cookie your application already issues, such as a session identifier. The ALB then issues an `AWSALBAPP` cookie of its own for the routing state and keys affinity to the presence of your cookie. The point is lifetime alignment: when your application's session expires or is invalidated on logout, the stickiness expires with it, instead of a load-balancer timer that knows nothing about your session model. In both modes the cookie contents are encrypted and meaningless to the target - do not try to parse them, and never treat them as an identity. ## Why anyone turns it on Usually one of three reasons. The application keeps session state in process memory, so a user bouncing between targets loses their cart or their login. Or an expensive per-user cache warms on one target and a different target has to rebuild it. Or a long-lived protocol - a WebSocket, a multi-step upload - genuinely needs the same peer for its duration, though a persistent connection already sticks to a target for its own lifetime without help. ## What actually breaks **A target going away discards the guarantee.** Affinity is best-effort, not durable. When a target is deregistered, fails a health check, or is replaced during a rolling deploy, its pinned clients are rerouted to a different target and whatever lived only in the old process is gone. Any deploy, scale-in, or instance replacement is therefore a partial session outage - which is exactly the event stickiness was adopted to avoid. **Load skews.** New targets from a scale-out receive only new clients, because existing clients keep their pin. Right when you added capacity because the fleet was hot, the hot instances stay hot. In the worst case one target holds a disproportionate share of heavy sessions and you cannot rebalance without breaking sessions on purpose. **Non-browser clients never stick.** A mobile app, a service-to-service caller, or a load-test tool that ignores `Set-Cookie` distributes across the fleet as if stickiness were off. If a feature depends on affinity, it will work in the browser and fail everywhere else - a bug that survives QA and appears in production. **It hides the real defect and calcifies it.** Every month of stickiness makes the in-memory session harder to remove, because more behaviour quietly assumes it. ## The alternative, and when stickiness is still right The durable answer is to make targets stateless: move session state to a shared store - a managed cache or a key-value database - and let any target serve any request. Then a deploy is invisible, scale-out rebalances immediately, and target replacement costs nothing. Stickiness remains legitimate as a bridge while that refactor happens, for a vendor application you cannot change, or as an optimisation where the consequence of losing affinity is a slower request rather than a broken one. Treat it that way explicitly - and if it is enabled, set the duration to the shortest value that works, so the fleet has a natural rebalancing rhythm. ## One detail worth knowing Stickiness on a target group pins a client to a target *within* that group. When a listener rule forwards to several weighted target groups - a canary or blue/green split - there is a separate target-group stickiness setting on the forward action, which keeps a client on the same *group* for a configured period. They are different controls: one chooses the version, the other chooses the instance. Enable both if a user must neither switch versions mid-session nor lose an in-memory session.

  • Why would you choose application-based stickiness over duration-based?
    To align the sticky window with the real session. Duration-based affinity is a wall-clock timer that keeps pinning a user after logout and drops them mid-session when it expires. Application-based affinity follows a cookie your app controls, so logout and session expiry end the pin at the right moment.
  • You enable stickiness and a load test still spreads perfectly evenly across targets. Why?
    The test client almost certainly is not storing and replaying `Set-Cookie` values. ALB affinity is entirely cookie-driven, so any client that discards cookies is routed by the normal algorithm. Configure a cookie jar in the test tool, otherwise the test is not exercising the production path at all.
  • Does stickiness protect a user's session during a rolling deployment?
    No. When the target holding a user's pin is deregistered, the ALB routes that user to another target and any in-process state is lost. Stickiness only avoids gratuitous hopping between healthy targets; surviving a deploy requires session state outside the process.

saying these in an interview costs you the question

  • Stickiness is a listener setting on the ALB.
  • A sticky client always reaches the same target, even after it is replaced.
  • The application should read the AWSALB cookie to identify the user.
  • Stickiness fixes load imbalance across targets.
  • Duration-based stickiness slides forward on every request.

context