Right, let’s talk about sticky sessions. You’ve probably built an app where a user adds something to their cart, and on the next click, it’s gone. Poof. Annoying, right? The culprit is often that their request got routed to a different backend instance that doesn’t know about their session. Sticky sessions, or session affinity if you’re feeling fancy, are ELB’s answer to this. It’s the feature that lets you say, “For the love of all that is holy, send this user’s requests to the same target until further notice.”

But here’s the thing: ELB gives you two completely different ways to do this, and picking the wrong one is a classic “it works on my machine” to “why is production on fire?” pipeline. Let’s break them down.

Duration-Based Stickiness: The Simple Sledgehammer

This is the older, simpler method. You tell the ELB, “Hey, see this user? Hammer their requests to the same instance for the next X seconds.” It’s dumb, it’s effective, and it’s entirely based on a cookie that the load balancer itself creates and manages.

The ELB generates a cookie named AWSALB (for Application Load Balancer) or AWSELB (for the older Classic Load Balancer) with an expiration time you set. This cookie contains the information the ELB needs to map the user back to the correct target.

Here’s how you enable it on a Target Group. Notice the app_cookie section is empty; we’re not using that yet.

resource "aws_lb_target_group" "example_duration" {
  name     = "tg-duration-sticky"
  port     = 80
  protocol = "HTTP"
  vpc_id   = aws_vpc.main.id
  target_type = "instance"

  stickiness {
    type            = "lb_cookie"
    cookie_duration = 86400 # 24 hours in seconds
    enabled         = true
  }
}

Why you might use it: It’s dead simple to configure. If your application is legacy or can’t be modified to generate its own session cookies, this is your only option.

The Pitfalls: This is a blunt instrument. Let’s say you set the duration for 24 hours. If the target instance fails or you take it out of service for a deployment, the ELB has no idea. It will keep dutifully trying to send that user to a dead instance until the cookie expires a day later. The user gets a flurry of 502 errors and probably rage-quits. You’ve traded a potential session issue for a guaranteed availability issue. The duration is also a guess. Set it too short, and you break long-lived sessions. Set it too long, and you exacerbate the problem of imbalanced traffic if a lot of users connect and then leave.

Application-Based Stickiness: The Surgical Scalpel

This is the modern, smarter approach. Instead of the ELB making up its own cookie, you delegate that responsibility to your application. The ELB looks for a specific cookie you define, and if it finds it, it routes the request based on that.

You configure your application to set a cookie upon login or session start. Let’s say you call it MY_APP_SESSION.

// Example in a Node.js/Express app
app.post('/login', (req, res) => {
  // ... authenticate user ...
  // Set a custom session cookie for stickiness
  res.cookie('MY_APP_SESSION', req.sessionID, {
    maxAge: 24 * 60 * 60 * 1000, // 24 hours
    httpOnly: true,
    secure: true
  });
  res.send('Logged in!');
});

Then, you tell the ELB, “Hey, buddy, whenever you see a cookie named MY_APP_SESSION, use that to stick the user.” You do this by setting the stickiness type to app_cookie and specifying the cookie name.

resource "aws_lb_target_group" "example_app" {
  name     = "tg-app-sticky"
  port     = 80
  protocol = "HTTP"
  vpc_id   = aws_vpc.main.id
  target_type = "instance"

  stickiness {
    type            = "app_cookie"
    cookie_name     = "MY_APP_SESSION"
    enabled         = true
  }
}

Why this is brilliant: The stickiness is now tied to the application’s concept of a session. When a user logs out, your application destroys their session and, crucially, stops sending the MY_APP_SESSION cookie. The next request from that user is treated as a new session and can be routed to any healthy instance. More importantly, if a target fails, the user’s next request (which still contains the cookie) will be routed to a new, healthy target. The ELB sees the cookie, decodes which target it should go to, notices that target is down, and chooses a new one. The user might experience a quick re-authentication but not a complete failure.

The Catch: Your application must be able to generate this cookie. If it can’t, this method is a non-starter. You also have to manage the cookie’s security attributes (HttpOnly, Secure) yourself.

So, Which One Should You Use?

Unless you’re dealing with a black-box application you can’t modify, always prefer application-based stickiness. It’s more resilient, more intelligent, and directly aligns your infrastructure’s behavior with your application’s logic. Duration-based stickiness is a legacy method that introduces unnecessary risk. It’s like using a permanent marker for a whiteboard schedule instead of a dry-erase marker. It works, but cleaning up the mess later is going to be a nightmare. Use the smarter tool. Your on-call phone will thank you.