6.4
Stickiness, Cross-Zone, TLS/SNI and Deregistration Delay
Session affinity cookies, cross-zone traffic maths, certificates and SNI, and draining in-flight requests.
28 min Reading + animations
Tip: tap or hover any dotted-underlined term to see what it means.
By the end of this lesson you will be able to
- Explain sticky sessions (session affinity), set up duration-based and application-based cookies on an ALB, and know how NLB, GWLB and CLB do stickiness.
- Explain why a user still loses the cart when a sticky server dies (session ID vs session data), and fix it properly with ElastiCache or DynamoDB.
- Work out the share of traffic every target gets with cross-zone load balancing on and off, and know the default and the billing for each load balancer type.
- Describe SSL vs TLS, certificates, public CAs and ACM, and choose between TLS termination, re-encryption and NLB passthrough.
- Configure an HTTPS listener: default certificate, certificate list and security policy, and explain how SNI picks the right certificate for each domain.
- Set the deregistration delay (connection draining) and slow start for scale-in, deployments and long requests.
- Recognise every exam pattern for these four features.
#Four features every load balancer setup touches
Lessons 6.2 and 6.3 built the load balancer: listeners, rules, target groups and health checks. This lesson covers four settings that decide how it behaves under real traffic:
| Feature | Question it answers | Where you set it |
|---|---|---|
| Sticky sessions | Should one user always reach the same target? | Target group (ALB, NLB, GWLB); listener (CLB) |
| Cross-zone load balancing | May a load balancer node in one AZ send traffic to targets in another AZ? | Load balancer (NLB, GWLB, CLB) and target group (ALB, NLB) |
| TLS and SNI | Where is HTTPS decrypted, with which certificate, for which domain? | Listener (certificates, security policy) |
| Deregistration delay | How long may a target finish its in-flight requests before it is removed? | Target group (ALB, NLB, GWLB); load balancer (CLB: connection draining) |
#Sticky sessions (session affinity)
#Why a user can land on a different server every time
By default a load balancer routes every request on its own. An ALB uses round robin (or least outstanding requests) per request, so one user’s clicks are spread over all targets. That is exactly what you want, unless the application keeps the user’s state in the memory of one server: a shopping cart, a login session, a half-filled form.
Then the first click lands on web-1, which puts the shirt in its RAM; the second click lands on web-2, which has never heard of the shirt. The user sees items appearing and disappearing, or is asked to log in again and again.
Sticky sessions (also called session affinity) make the load balancer send all requests from one client to the same target for a while.
#How an ALB makes a client stick: cookies
An ALB remembers the target in a cookie it gives the browser. Stickiness is switched on per target group, and you choose one of two types:
| Duration-based | Application-based | |
|---|---|---|
| Who decides how long? | The load balancer: the stickiness duration you set | Your application: stickiness follows the application’s own session cookie |
| Cookie the target sets | None needed | A custom cookie with a name you configure (for example app_session), any attributes the app needs |
| Cookie the load balancer sets | AWSALB | AWSALBAPP (shown to the client as AWSALBAPP-0 … AWSALBAPP-3, because a large cookie is split into up to 4 parts) |
| Duration setting | 1 second to 7 days, default 1 day | 1 second to 7 days, default 1 day |
| Use it when | The app has no session cookie of its own | The app already has a session cookie and stickiness should last as long as that session |
| Several ALB layers | Only one layer can use it (the name AWSALB is fixed) | Works on every layer (each target group has its own cookie name) |
Details worth knowing:
- The load balancer’s cookies are encrypted with a rotating key. They contain a pointer to a target, never user data, and you cannot read or edit them.
- The ALB resets the expiry on every request, so an active user stays stuck; a user idle for longer than the duration gets a new target.
- For cross-origin (CORS) requests the ALB also sets
AWSALBCORSwithSameSite=None; Secure, so browsers send it on cross-site calls. - Reserved names: an application cookie name may not start with
AWSALB,AWSALBAPPorAWSALBTG. (AWSALBTGis used for stickiness to a target group when a listener rule forwards to several weighted target groups; that is set on the rule, and lesson 6.3 shows weighted forwarding.) - The client must accept cookies. A client that drops cookies is routed fresh on every request.
- If the sticky target is unhealthy, deregistering or gone, the ALB ignores the cookie, chooses a healthy target and updates the cookie. The user is re-stuck there.
- WebSocket connections are naturally sticky: after the upgrade, the whole connection stays on one target.
- Restrictions: stickiness does not work when the target group has cross-zone turned off, with the weighted random routing algorithm, or with application-based cookies on weighted target groups.
#Stickiness on NLB, GWLB and CLB
| Load balancer | How it sticks | Notes |
|---|---|---|
| ALB | Cookies: AWSALB (duration) or custom + AWSALBAPP (application) | Configured per target group |
| NLB | Source IP address (source_ip) | No cookies: an NLB works at layer 4 and never reads HTTP. Not supported on TLS or QUIC listeners. Everyone behind one NAT gateway or corporate proxy shares an IP and lands on one target. |
| GWLB | Flow hashing: 5-tuple by default, or 3-tuple / 2-tuple (source_ip_dest_ip_proto, source_ip_dest_ip) | Keeps both directions of a flow on the same appliance (lesson 6.3) |
| CLB | Duration-based cookie AWSELB, or application-controlled (follows the app’s cookie) | Configured per listener; CLB is the legacy generation |
The slides say stickiness “works for CLB, ALB and NLB”, and it does, but only CLB and ALB use cookies with an expiry you control. The NLB has no cookie and no duration: it hashes the client’s IP.
#Session ID vs session data: why the cart is still lost when a server dies
This is the question that confuses almost everyone: “The cookie is in the user’s browser, so why is the cart lost when the server dies?”
The answer: the session ID and the session data are two different things, kept in two different places.
What the cookie holds: only the session ID
The cookie the load balancer gives the browser holds a token, roughly “this user belongs to web-1”. It does not hold the shirt and the trousers. It is the restaurant token, nothing more.
What the server holds: the session data
The real cart (2 shirts, 1 pair of trousers) is written in web-1’s RAM (or its local disk). Stickiness works by sending the user back to the one place where that data exists.
Normal flow
The user adds a shirt; web-1 stores it in RAM; the load balancer sets the cookie. The user adds trousers; the browser shows the cookie; the load balancer sends the request to web-1; web-1 combines the shirt from memory with the new trousers.
web-1 crashes or is terminated
The RAM is wiped, and the cart with it. The next request still carries the cookie saying “web-1”. The load balancer sees that web-1 is dead and is forced to pick web-2.
web-2 has never seen this user
web-2 looks in its own memory, finds nothing, and answers: “Your cart is empty.” With sticky sessions the session data is trapped inside one server. When the server dies, the data dies.
Sticky sessions and the shopping cart
Two web servers keep each user’s cart in their own memory (RAM). Watch what happens without stickiness, with a stickiness cookie, when the sticky server dies, and when the cart lives in ElastiCache instead.
Scenario
The user adds a shirt. The ALB picks web-1 with round robin, and web-1 writes the cart into its own RAM.
#The real fix: keep session data outside the servers
If the cart is written to a shared, external store instead of web-1’s RAM, it does not matter which server dies or which server the next request reaches. Every server reads the same data.
| Store | Why it fits sessions |
|---|---|
| Amazon ElastiCache (Valkey, Redis or Memcached) | In-memory, sub-millisecond reads, keys with a time to live (TTL), replication across AZs with Valkey or Redis |
| Amazon DynamoDB | Fully managed, durable, scales automatically, TTL deletes expired sessions for free |
| A token in the client (for example a signed JWT) | No server-side store at all, for small amounts of data such as identity |
This makes the web tier stateless: servers can crash, be terminated by Auto Scaling or be replaced in a deployment, and traffic still spreads evenly. Once state is external, stickiness is not needed.
#Downsides of stickiness
- Uneven load. Users stuck to a busy target stay there. After a scale-out, the new instances get only new users while the old ones stay overloaded. The longer the duration, the worse; a 7-day cookie can keep a fleet unbalanced for a week.
- Lost sessions. As shown above, stickiness does not protect state; it only hides the problem until a target fails, is scaled in or is replaced.
- NAT hot spots on an NLB: one office or one mobile carrier NAT sends thousands of users from one IP to one target.
- Fewer features: no stickiness with cross-zone off (ALB), with weighted random routing, or on NLB TLS listeners.
Self-checkQuestion
An online shop runs on six EC2 instances behind an ALB with duration-based stickiness. Whenever Auto Scaling terminates an instance, the customers who were on it find their carts empty. What should a solutions architect do to stop this?
#Cross-zone load balancing
#How traffic reaches a target: DNS, nodes, targets
When you enable an AZ for a load balancer, ELB places a load balancer node in that AZ. Traffic then flows in two hops:
- Client → node. The load balancer’s DNS name resolves to the IP addresses of its nodes, one per enabled AZ, with a 60-second TTL. Clients pick among them, so over many clients each node receives an equal share: 50/50 with two AZs, a third each with three. DNS does not know how many targets sit behind each node.
- Node → target. Each node chooses a target. Cross-zone load balancing decides which targets it may choose from:
- On: every registered target in all enabled AZs.
- Off: only targets in its own AZ.
#Worked example: 2 targets in one AZ, 8 in the other
The notes’ example: AZ a has 2 instances, AZ b has 8. DNS sends 50% of the traffic to each node.
| Each instance in AZ a | Each instance in AZ b | Busiest ÷ idlest | |
|---|---|---|---|
| Cross-zone off | 50% ÷ 2 = 25% | 50% ÷ 8 = 6.25% | 4× |
| Cross-zone on | 100% ÷ 10 = 10% | 100% ÷ 10 = 10% | 1× |
With cross-zone off, the two instances in AZ a are hammered while the eight in AZ b sit mostly idle. With it on, the load balancer ignores the AZ boundary and spreads the traffic evenly over all ten.
The general rule, with k AZs that have healthy targets, n targets in an AZ and N targets in total:
- Off: each target gets (1 ÷ k) ÷ n.
- On: each target gets 1 ÷ N.
- Traffic that crosses an AZ boundary when on: each node keeps only its own AZ’s share of targets, and on average (k − 1) ÷ k of requests go to another AZ: half with 2 AZs, two thirds with 3. That is the traffic an NLB or GWLB pays inter-AZ data transfer for.
Cross-zone load balancing: off vs on
The load balancer has one node in each AZ. DNS spreads clients evenly across the nodes, so each node receives half of the traffic. AZ a has 2 targets and AZ b has 4.
Scenario
A client resolves the load balancer’s DNS name. Route 53 answers with the IP addresses of the nodes, one per AZ, with a 60-second TTL. Over many clients, each node gets about half of the traffic.
#Defaults and billing for each load balancer type
| Load balancer | Default | Where you change it | Inter-AZ data when on |
|---|---|---|---|
| ALB | Always on at load balancer level | Can be turned off per target group (load_balancing.cross_zone.enabled=false) | Free |
| NLB | Off | On or off for the load balancer; override per target group | Charged (normal inter-AZ data transfer) |
| GWLB | Off | Load balancer attribute | Charged |
| CLB | On if created in the console, off if created with the API or CLI | Load balancer attribute | Free |
Two corrections to the notes: the NLB’s “extra charge” is not a fee for the feature but the regular inter-AZ data transfer charge for the bytes that cross AZs; and the ALB’s cross-zone, while always on at load balancer level, can be turned off per target group (since late 2022). The slides’ table is up to date on both.
#When would you turn it off?
Keeping traffic in its AZ has real benefits, and AWS documents them:
- No inter-AZ data charges on an NLB or GWLB.
- Zonal isolation: a problem in one AZ (a bad deployment, a gray failure) cannot spill into targets in another AZ.
- Slightly lower latency.
The price is capacity planning. With cross-zone off:
- each AZ must have enough targets for its share, and the AZs should have similar numbers of targets (an Auto Scaling group spread evenly across AZs does this for you, lesson 6.5);
- if every target in an AZ is unhealthy, the load balancer removes that node’s IP from DNS (DNS failover) and the other AZs take all the traffic;
- every target group behind the load balancer should use the same AZs: an AZ with no targets for a target group is treated as unhealthy, and an ALB returns 503 for requests that enter an empty AZ;
- on an ALB target group, sticky sessions and Lambda targets are not supported.
If you cannot guarantee even capacity per AZ, AWS’s advice is to keep cross-zone on.
Cross-zone traffic calculator
Set how many healthy targets each AZ has, pick the load balancer type and switch cross-zone on or off. Every bar is one target and its share of all requests.
Load balancer type
Cross-zone load balancing
NLB: off by default. Turn it on for the load balancer, or override it per target group. When it is on, the bytes that cross AZs pay normal inter-AZ data transfer charges.
AZ a · 2 targets
LB node gets 50% · 25% each
AZ b · 8 targets
LB node gets 50% · 6.25% each
AZ c · 0 targets
no healthy target: removed from DNS
#TLS on a load balancer
#SSL or TLS?
SSL (Secure Sockets Layer) is the original protocol for encrypting web traffic. All versions of SSL are broken and disabled today. TLS (Transport Layer Security) is its modern successor; current versions are TLS 1.2 and TLS 1.3. Every “HTTPS” padlock today is TLS, but people still say “SSL certificate” out of habit, and AWS’s own settings still use names like ELBSecurityPolicy and “SSL certificate”. In exam questions, read “SSL” as “TLS”.
Encryption between the client and the load balancer is called in-flight (or in-transit) encryption. It stops anyone on the path from reading or changing the traffic.
#Certificates, public CAs and ACM
A load balancer proves its identity with an X.509 certificate (a TLS server certificate). It contains the domain names it is valid for, a public key, a validity period, and the signature of a certificate authority (CA). The matching private key stays secret on the server. The browser trusts the certificate only if the name matches what the user typed, it has not expired, and a CA in the browser’s trust store signed it.
- Public CAs (Let’s Encrypt, GoDaddy, Comodo/Sectigo and others) issue certificates browsers trust. Certificates expire and must be renewed. The industry is shortening lifetimes: from 15 March 2026 public certificates may be valid for at most 200 days.
- AWS Certificate Manager (ACM) is the AWS way:
- Public certificates are free when used with integrated services (ELB, CloudFront, API Gateway).
- You prove you own the domain with DNS validation (a CNAME record, created for you in Route 53) or email validation.
- ACM renews its certificates automatically, as long as the DNS validation record stays in place, and redeploys them to the load balancer.
- The private key never leaves AWS: you cannot download a normal ACM certificate or install it on an EC2 instance.
- Imported certificates (bought from an outside CA and imported into ACM) are supported, but ACM cannot renew them: you must renew and re-import before they expire. ACM emits expiry events to EventBridge, and an AWS Config rule can flag expiring certificates.
- ACM certificates are Regional: a certificate for an ALB must be in the ALB’s Region; a certificate for CloudFront must be in us-east-1.
- Certificates can also be uploaded to IAM (the old way, still needed in Regions without ACM).
Side notes (2025–26): ACM public certificates are now issued with a 198-day validity (down from 395 days) and are renewed automatically 45 days before expiry, so nothing changes for you if you use ACM-issued certificates. ACM can also issue exportable public certificates (paid, about $7 per domain name) whose private key you can download and install on EC2 or on-premises servers. The exam still expects “ACM certificates cannot be exported; import or self-manage if the instance itself needs the certificate”.
#Where to decrypt: termination, re-encryption or passthrough
| TLS termination (offload) | End-to-end re-encryption | TLS passthrough | |
|---|---|---|---|
| Load balancer and listener | ALB HTTPS listener (or NLB TLS listener) | ALB HTTPS listener + HTTPS target group (or NLB TLS listener + TLS target group) | NLB TCP listener on 443 |
| Who holds the client-facing certificate | The load balancer (from ACM) | The load balancer (from ACM) | The targets |
| Load balancer → target | Plain HTTP (or TCP) inside the VPC | Encrypted again with a new TLS session | The client’s original encrypted bytes, untouched |
| Can the load balancer route on path, host, cookies? | Yes | Yes | No, it never sees HTTP |
| CPU cost on targets | None for TLS | Some (TLS to the load balancer) | Full TLS work |
| Typical reason | The default: offload CPU, one place to manage certificates | Compliance: “encrypted on every hop” | The load balancer must never see plain text; the app does its own mutual TLS |
- With re-encryption, the target needs its own certificate, but the ALB does not validate target certificates, so a self-signed certificate is fine.
- After termination the ALB adds
X-Forwarded-Proto: https(andX-Forwarded-Forwith the client’s IP) so the application knows how the user connected. - An ALB can also do mutual TLS (mTLS) with clients, verifying client certificates against a trust store, without passthrough.
Where is TLS decrypted?
The browser always speaks HTTPS. What changes is who holds the certificate and private key, and whether the traffic behind the load balancer is encrypted.
Scenario
ACM gives the ALB a certificate for www.shop.example. ACM keeps the private key; you never download it, and ACM renews the certificate by itself.
#The HTTPS listener: default certificate, certificate list, security policy
An HTTPS listener on an ALB (or a TLS listener on an NLB) has three TLS settings:
| Setting | What it is |
|---|---|
| Default certificate | Exactly one, required. Used when the client sends no SNI, or when no certificate in the list matches the requested name. |
| Certificate list | Optional extra certificates, so one listener can serve many domains with their own certificates. Up to 25 per ALB by default (not counting the default), adjustable. The load balancer chooses among them with SNI. |
| Security policy | Which TLS versions and ciphers the listener accepts. Choose a strict policy for modern clients, or an older one to support legacy clients. |
Security policy defaults today:
- A listener created in the console gets
ELBSecurityPolicy-TLS13-1-2-Res-PQ-2025-09: TLS 1.3 and 1.2 only, a restricted set of strong ciphers, and post-quantum key exchange. - A listener created with the CLI, CloudFormation or CDK without a policy gets the older
ELBSecurityPolicy-2016-08, which still accepts TLS 1.0 and 1.1. Name a modern policy explicitly in your templates. - If old devices that only speak TLS 1.0 must still connect, attach a policy that includes TLS 1.0. That is what the slides mean by “a security policy to support older versions of SSL/TLS”.
#Classic Load Balancer: one certificate
The CLB (v1) supports one certificate per listener and no SNI. To serve several domains with different certificates on a CLB you need one CLB per domain (or one certificate that lists every name as a Subject Alternative Name). The ALB and NLB (v2) support multiple certificates on a listener, using SNI.
#SNI (Server Name Indication)
#The problem SNI solves
Picture one load balancer serving www.cats.com and www.dogs.com. The TLS handshake happens before any HTTP is sent, so when a connection arrives the server cannot read the Host header yet. It does not know which site the user wants, so it does not know which certificate to show. Before SNI it always showed the same one: a visitor to dogs.com received the cats.com certificate and the browser displayed a red “Not secure” warning.
The old fix was one IP address per HTTPS site, which meant one load balancer per site. Expensive, and IPv4 addresses are scarce.
#How SNI works
SNI is an extension to TLS. In the very first handshake message, the ClientHello, the browser includes the hostname it wants, in plain text: “I am here for www.dogs.com”. The server reads it and answers with the matching certificate.
On an ALB the selection works like this:
- The client sends a hostname with SNI.
- If exactly one certificate in the list matches it (by its common name or a Subject Alternative Name, wildcards included), the ALB uses that one.
- If several match, the ALB picks the best one the client supports (elliptic-curve keys before RSA, then not expired, stronger hash, longer key).
- If the client sent no SNI or nothing matches, the ALB uses the default certificate, which usually means a name mismatch error for the client.
SNI only chooses the certificate. Which target group gets the request is still decided by the listener rules (usually a host-header rule) after decryption.
SNI: one ALB, many certificates
One HTTPS listener serves www.cats.example (the default certificate) and www.dogs.example (in the certificate list). Each site has its own target group.
Scenario
The user types www.dogs.example. In the very first handshake message, before anything is encrypted, the browser names the site it wants. That field is Server Name Indication.
#Who supports SNI
- ALB: yes, multiple certificates per HTTPS listener.
- NLB: yes, multiple certificates per TLS listener.
- CloudFront: yes (SNI is its default and free; a dedicated IP per distribution costs extra).
- CLB: no, one certificate per listener.
Practically every client made in the last 15 years sends SNI. The ones that do not are very old browsers and operating systems, old Java and Python libraries, and some embedded devices.
One more fact: because the SNI hostname travels in plain text, anyone watching the network can see which site you visit, though not what you do there. The newer Encrypted Client Hello extension hides it, but it is not yet common and is not on the exam.
Self-checkQuestion
A company serves three websites, each with its own domain and its own TLS certificate. Today it runs three Classic Load Balancers. It wants one load balancer, HTTPS for all three domains, and less CPU load on its instances. What should it do?
#Deregistration delay (connection draining)
#What happens when a target is removed
A target leaves a target group when Auto Scaling scales in, when a deployment replaces it, or when you deregister it by hand. The load balancer does not cut it off instantly:
Draining starts
The target enters the
drainingstate. The load balancer stops sending it new requests; every new request goes to the other targets.In-flight requests finish
Requests that were already in progress on the target are allowed to complete, for up to the deregistration delay.
Done
When the target has no in-flight requests and no active connections, the ALB completes the deregistration early, without waiting for the full delay. Otherwise, when the delay runs out, the target becomes
unusedand any connections still open are closed (clients see a 5xx error). If the target belongs to an Auto Scaling group, Auto Scaling waits for this before terminating the instance.
| ALB / NLB / GWLB | CLB | |
|---|---|---|
| Name | Deregistration delay | Connection draining |
| Where | Target group attribute deregistration_delay.timeout_seconds | Load balancer attribute |
| Range | 0–3600 seconds (0 turns it off) | 1–3600 seconds when enabled |
| Default | 300 seconds | 300 seconds (on by default in the console, off through the API/CLI) |
NLB extras: QUIC traffic always uses 300 seconds; the attribute deregistration_delay.connection_termination.enabled closes the remaining connections at the end of the delay (otherwise an idle-but-open TCP connection can keep receiving traffic); AWS recommends at least 120 seconds on an NLB.
#Choosing the value
- Short requests (APIs answering in milliseconds): a low value such as 30 seconds is plenty. A long delay only slows scale-in and deployments.
- Long requests (uploads, reports, video processing): set the delay longer than the longest request, or the end of it is cut off.
- Long-lived connections (WebSockets, long polling, HTTP keep-alive that never idles): they never “finish”, so the drain always runs to the full delay. Make the application close connections when it is told to stop (on
SIGTERM), so clients reconnect elsewhere. - 0 means no draining: in-flight requests are dropped. Use it only for tests or stateless, instantly retried traffic.
Deregistration delay during scale-in
An Auto Scaling group is attached to the target group. When it removes web-1, the load balancer first drains it. The delay is a target group setting: 300 seconds by default, 0 to 3600 allowed.
Scenario
A user’s checkout request is being processed on web-1. It takes a few seconds.
#Slow start mode (ALB)
Draining protects targets that are leaving. Slow start protects targets that are arriving. A fresh instance with cold caches or a runtime that is still warming up can be overwhelmed if it gets its full share of requests the moment it passes its health check.
- With slow start on, a new healthy target’s share rises linearly over the slow start duration: 30 to 900 seconds (default 0, off).
- It is an ALB target group setting and works with the round robin algorithm only, not with least outstanding requests or weighted random.
- A target that already existed when you turned slow start on does not enter slow start, and a newly registered target enters it only when at least one other healthy target is not in slow start.
#How these features fit together in system design
- Stateless web tier first. Put sessions in ElastiCache or DynamoDB, files in S3 or EFS. Then stickiness is unnecessary, scale-in is safe, and any target can serve any request. Keep stickiness for legacy applications you cannot change, with a short duration.
- Leave cross-zone on for ALBs. For NLBs, turn it on when targets are uneven across AZs or when even load matters more than the inter-AZ data bill; leave it off when you want zonal isolation and you spread targets evenly with Auto Scaling.
- Terminate TLS at the load balancer with ACM certificates by default; add an HTTPS target group when compliance requires encryption on every hop; use NLB passthrough only when the load balancer must never decrypt. Use a modern security policy and put all your domains on one listener with SNI.
- Tune draining to your request length: 30 seconds for APIs, longer than the longest upload for upload services, and add slow start for instances that need to warm up.
- Watch the metrics: per-target
RequestCount(imbalance from stickiness or cross-zone),HTTPCode_ELB_5XX_Count(draining too short, empty AZ), and ACM certificate expiry for imported certificates.
#Try it yourself
# Variables: your target group, listener and load balancer
TG=arn:aws:elasticloadbalancing:us-east-1:111122223333:targetgroup/web/0123456789abcdef
LISTENER=arn:aws:elasticloadbalancing:us-east-1:111122223333:listener/app/web-alb/50dc6c495c0c9188/f2f7dc8efc522ab2
NLB=arn:aws:elasticloadbalancing:us-east-1:111122223333:loadbalancer/net/tcp-nlb/1234567890abcdef
# 1. Duration-based stickiness for one hour
aws elbv2 modify-target-group-attributes --target-group-arn $TG --attributes \
Key=stickiness.enabled,Value=true Key=stickiness.type,Value=lb_cookie \
Key=stickiness.lb_cookie.duration_seconds,Value=3600
# ...or application-based stickiness that follows the app's app_session cookie
aws elbv2 modify-target-group-attributes --target-group-arn $TG --attributes \
Key=stickiness.enabled,Value=true Key=stickiness.type,Value=app_cookie \
Key=stickiness.app_cookie.cookie_name,Value=app_session \
Key=stickiness.app_cookie.duration_seconds,Value=86400
# 2. See the cookie: the response carries AWSALB and AWSALBCORS
curl -sI https://www.shop.example/ | grep -i set-cookie
# 3. Cross-zone: turn it on for an NLB (inter-AZ data charges apply)...
aws elbv2 modify-load-balancer-attributes --load-balancer-arn $NLB \
--attributes Key=load_balancing.cross_zone.enabled,Value=true
# ...or turn it off for one ALB target group
aws elbv2 modify-target-group-attributes --target-group-arn $TG \
--attributes Key=load_balancing.cross_zone.enabled,Value=false
# 4. A free ACM certificate with DNS validation
aws acm request-certificate --domain-name www.dogs.example \
--subject-alternative-names dogs.example --validation-method DNS
aws acm describe-certificate --certificate-arn $CERT \
--query "Certificate.[Status,RenewalEligibility,NotAfter]"
# 5. HTTPS listener: default certificate + modern security policy, then SNI certificates
aws elbv2 modify-listener --listener-arn $LISTENER \
--certificates CertificateArn=$CATS_CERT \
--ssl-policy ELBSecurityPolicy-TLS13-1-2-Res-PQ-2025-09
aws elbv2 add-listener-certificates --listener-arn $LISTENER \
--certificates CertificateArn=$DOGS_CERT
aws elbv2 describe-listener-certificates --listener-arn $LISTENER
# 6. Watch SNI choose the certificate (and the default one when SNI is missing)
openssl s_client -connect web-alb-123456.us-east-1.elb.amazonaws.com:443 \
-servername www.dogs.example </dev/null 2>/dev/null | openssl x509 -noout -subject
openssl s_client -connect web-alb-123456.us-east-1.elb.amazonaws.com:443 \
-noservername </dev/null 2>/dev/null | openssl x509 -noout -subject
# 7. Draining: 30 s for a short-request API, and slow start of 2 minutes
aws elbv2 modify-target-group-attributes --target-group-arn $TG --attributes \
Key=deregistration_delay.timeout_seconds,Value=30 \
Key=slow_start.duration_seconds,Value=120
# 8. Deregister a target and watch it drain
aws elbv2 deregister-targets --target-group-arn $TG --targets Id=i-0abc1234def567890
aws elbv2 describe-target-health --target-group-arn $TG \
--query "TargetHealthDescriptions[].[Target.Id,TargetHealth.State]" # draining → unused
#Summary
Key takeaways
- Sticky sessions send one client to the same target. ALB: duration-based cookie
AWSALBor application-based (your cookie +AWSALBAPP), set per target group, duration 1 s to 7 days, default 1 day; names starting withAWSALB,AWSALBAPP,AWSALBTGare reserved. CLB:AWSELB. NLB: source IP, no cookies. GWLB: flow hashing. - The cookie holds only the session ID; the session data lives in the server’s RAM. When that server dies, the cart dies. The real fix is an external session store, ElastiCache or DynamoDB, which makes the tier stateless and stickiness unnecessary.
- Stickiness causes imbalance (worse with long durations and NAT) and does not work with ALB cross-zone off or weighted random routing.
- Cross-zone: DNS splits traffic evenly over the nodes; with cross-zone off each node uses only its AZ’s targets (2 + 8 targets → 25% vs 6.25%), with it on every target gets an equal share (10% each).
- ALB: always on at load balancer level, free, can be turned off per target group. NLB / GWLB: off by default, inter-AZ data charges when on. CLB: on in the console, off via API/CLI, free.
- TLS replaced SSL; certificates come from public CAs or ACM (free public certificates, automatic renewal, private key stays in AWS; imported certificates are not renewed; CloudFront needs us-east-1).
- Termination at the load balancer offloads CPU; re-encryption (HTTPS target group) keeps every hop encrypted; NLB TCP passthrough leaves decryption to the targets.
- An HTTPS listener has one default certificate, an optional certificate list (25 per ALB by default) and a security policy (TLS versions and ciphers; legacy policies for old clients).
- SNI: the client puts the hostname in the ClientHello, and the load balancer picks the matching certificate. ALB, NLB and CloudFront support it; CLB does not (one certificate). No SNI or no match → default certificate.
- Deregistration delay (CLB: connection draining): default 300 s, 0–3600 s, per target group. Draining targets get no new requests while in-flight ones finish. Raise it if scale-in drops requests; lower it for short requests and faster deployments. Slow start (30–900 s) ramps up new ALB targets.
Answer on your own first, then read the explanation, even when you got it right.
Self-checkQuestion
What is the name of the cookie an Application Load Balancer creates for duration-based sticky sessions?
Self-checkQuestion
What stickiness duration can you configure for a duration-based ALB cookie?
Self-checkQuestion
How does a Network Load Balancer implement sticky sessions?
Self-checkQuestion
Which two statements about sticky sessions on an Application Load Balancer are true?
Choose 2
Self-checkQuestion
Users of a legacy web application behind an ALB complain that items randomly disappear from their shopping carts. The application keeps carts in server memory, and the code cannot be changed this quarter. What is the quickest fix?
Self-checkQuestion
An application already uses ALB stickiness. Customers still lose their carts whenever Auto Scaling terminates an instance during scale-in. The company wants sessions to survive any instance failure. What should a solutions architect recommend?
Self-checkQuestion
An application sets its own session cookie called app_session and expires it when the user logs out. The ALB should keep each user on one target for exactly as long as that session lasts. How should stickiness be configured?
Self-checkQuestion
An ALB target group uses duration-based stickiness of 7 days. After a traffic spike, Auto Scaling added four instances, but the four original instances stay above 85% CPU while the new ones idle near 10%. What is the best course of action?
Self-checkQuestion
A load balancer has cross-zone load balancing turned off. AZ a has 2 healthy instances and AZ b has 8. What share of all traffic does each instance in AZ b receive?
Self-checkQuestion
An ALB (cross-zone on) has 2 instances in AZ a, 3 in AZ b and 5 in AZ c, all healthy. What share of the traffic does each instance get?
Self-checkQuestion
The same 2 + 3 + 5 instances sit behind an NLB with cross-zone load balancing off. What share does the busiest instance receive?
Self-checkQuestion
Which two statements about cross-zone load balancing defaults and billing are correct?
Choose 2
Self-checkQuestion
CloudWatch shows that the CPU utilization of EC2 instances behind a Network Load Balancer is very uneven: instances in us-east-1a run at 80% while those in us-east-1b run at 20%. us-east-1a has fewer instances. What should a solutions architect do?
Self-checkQuestion
An NLB with cross-zone load balancing off has targets in two AZs. Every target in AZ a fails its health checks. What happens to client traffic?
Self-checkQuestion
An engineer turns off cross-zone load balancing on an ALB target group, then tries to enable duration-based stickiness on it. The change fails. Why?
Self-checkQuestion
Which two statements describe TLS termination at an Application Load Balancer?
Choose 2
Self-checkQuestion
A healthcare company must keep data encrypted on every network hop, including inside the VPC. The application also needs path-based routing to different services. Which design meets both requirements?
Self-checkQuestion
A bank’s security policy says the load balancer must never have access to decrypted traffic; the instances perform their own TLS, including client certificate checks. Which option fits?
Self-checkQuestion
What must every HTTPS listener on an ALB have?
Self-checkQuestion
A company wants to serve shop.example.com, blog.example.net and api.example.org over HTTPS from one ALB, each with its own certificate. What makes this possible?
Self-checkQuestion
An old client that does not support SNI connects to an ALB listener that has a default certificate for www.cats.example and a certificate for www.dogs.example in its list. The client wants www.dogs.example. What happens?
Self-checkQuestion
Which load balancer does NOT support SNI with multiple certificates?
Self-checkQuestion
Which two statements about AWS Certificate Manager are true?
Choose 2
Self-checkQuestion
A company has thousands of industrial devices that support only TLS 1.0. They must connect to a new ALB whose listener was created in the console with the default settings, and the handshakes fail. What should a solutions architect change?
Self-checkQuestion
What are the default value and the allowed range of the deregistration delay on an ALB target group?
Self-checkQuestion
An Auto Scaling group behind an ALB scales in every evening. Users who are uploading files at that moment get 502 errors. The deregistration delay is set to 0. What should be done?
Self-checkQuestion
A team deploys a REST API whose requests finish in under 500 ms. Each rolling deployment takes far longer than expected because every replaced instance stays in the draining state for 5 minutes. What is the best change?
Self-checkQuestion
Which two statements about deregistration delay are true?
Choose 2
Self-checkQuestion
New instances launched by Auto Scaling behind an ALB return slow responses and timeouts for the first minute after they pass their health check, because their caches are cold. The target group uses round robin. What should a solutions architect enable?
Self-checkQuestion
Study notes say: ‘Cross-zone is on by default on the ALB (free) and off on the NLB (extra charge if turned on).’ What is the most accurate version today?