AWS Elastic Load Balancer TCP/UDP stickiness
An AWS Elastic Load Balancer provides a Layer 4 entry point for internet-facing services. A Network Load Balancer (NLB) supports TCP and UDP listeners, forwards traffic to healthy targets and works with instance or IP address targets.
Stickiness adds source-based affinity: TCP connections and UDP flows from the same client address normally reach the same target. This is consistent hashing, not cookie-based session persistence, so it suits protocol-aware backends that need stable client addressing without interpreting HTTP headers.
The walkthrough uses AWS CLI commands and placeholders for a public NLB across two availability zones. Replace every example value, use Elastic IP addresses when fixed public addressing is required, and register healthy application targets before sending production traffic.
Australian operators should treat load-balancer placement as both a network and governance decision. Sydney and Melbourne AWS regions can support local latency and data-placement requirements, while Privacy Act 1988 and Notifiable Data Breaches obligations can apply to logs containing client IP addresses.
Prepare the network foundation
Use separate subnets in at least two availability zones, for example ap-southeast-2 in Sydney and ap-southeast-4 in Melbourne, subject to availability in your account. Place the NLB in public subnets and application instances in private subnets, with outbound access through NAT or the required VPC endpoints.
Allow TCP 443 and UDP 53 from the client ranges that need them, then permit the targets to reach required application ports. Keep the public surface narrow: clients behind Australian ISP NAT can share one public address, so source-IP hashing may group unrelated users on the same target.
Create target groups and health checks
Create a TCP target group and a UDP target group. For TCP, probe the traffic port. For UDP, run a small HTTP health endpoint on port 8080 that returns 200 only when the service is ready. NLB health checks for UDP target groups use TCP or HTTP, never a UDP probe.
Allow these checks from the NLB subnet CIDRs on their health-check ports. A TCP check proves reachability rather than application readiness, so use a readiness-aware endpoint where possible.
aws elbv2 create-target-group \
--name au-tcp-443 --protocol TCP --port 443 \
--vpc-id vpc-... --target-type instance \
--health-check-protocol TCP --health-check-port traffic-port \
--health-check-interval-seconds 10 \
--healthy-threshold 3 --unhealthy-threshold 3
aws elbv2 create-target-group \
--name au-udp-53 --protocol UDP --port 53 \
--vpc-id vpc-... --target-type instance \
--health-check-protocol HTTP --health-check-port 8080 \
--health-check-path /healthy \
--health-check-interval-seconds 10 \
--healthy-threshold 3 --unhealthy-threshold 3
Attach the TCP and UDP listeners
Create the NLB with the two subnets and its security group, then attach one listener per protocol. TCP 443 and UDP 53 below are examples; both listeners must forward to their matching target groups.
Set NLB_ARN, TCP_TG_ARN and UDP_TG_ARN to the ARNs returned by the earlier commands, then create the listeners.
aws elbv2 create-load-balancer \
--name au-edge-nlb --type network \
--scheme internet-facing \
--subnets subnet-sydney subnet-melbourne \
--security-groups sg-...
aws elbv2 create-listener \
--load-balancer-arn "$NLB_ARN" \
--protocol TCP --port 443 \
--default-actions "Type=forward,TargetGroupArn=$TCP_TG_ARN"
aws elbv2 create-listener \
--load-balancer-arn "$NLB_ARN" \
--protocol UDP --port 53 \
--default-actions "Type=forward,TargetGroupArn=$UDP_TG_ARN"
Register each instance on its protocol-specific port.
aws elbv2 register-targets \
--target-group-arn "$TCP_TG_ARN" \
--targets Id=i-0123456789abcdef0,Port=443
aws elbv2 register-targets \
--target-group-arn "$UDP_TG_ARN" \
--targets Id=i-0123456789abcdef0,Port=53
Enable source IP stickiness
Enable client IP stickiness on both target groups. NLB uses consistent hashing of client connection attributes, keeping new flows on one target while it remains healthy. It does not store application session state or add reliable delivery to UDP.
For instance targets, source client IP preservation is enabled by default, so backends can see the original client address. Cookie stickiness is not the mechanism for these raw listeners.
aws elbv2 modify-target-group-attributes \
--target-group-arn "$TCP_TG_ARN" \
--attributes Key=stickiness.enabled,Value=true
aws elbv2 modify-target-group-attributes \
--target-group-arn "$UDP_TG_ARN" \
--attributes Key=stickiness.enabled,Value=true
Protect targets and control access
Configure two security layers. The NLB security group limits client access to published ports and allows outbound traffic to targets. Because instance targets preserve the client source IP, application traffic arrives from client ranges. Permit that traffic on service ports and health checks from the NLB subnet CIDRs on health-check ports.
Do not simply allow every source to the target ports. Revalidate target rules whenever the NLB security group changes. For public DNS, allow UDP 53 and TCP 53 where your resolver design needs fallback over TCP.
Test traffic and verify affinity
Register instances, wait for healthy targets, and test through the NLB DNS name rather than an Elastic IP. From an approved client, run nc -vz <nlb-dns-name> 443 for TCP and nc -vzu <nlb-dns-name> 53 for UDP. A UDP test needs an application-level reply because a silent datagram proves little.
Open several TCP connections from one client and compare target identifiers in application logs; do the same with UDP requests and source addresses. Review NLB flow logs, target logs, ActiveFlowCount, NewFlowCount and UnHealthyHostCount. Raise the TCP or UDP idle timeout for unusually quiet, long-lived flows.
Operate for reliability and Australian compliance
During scaling or maintenance, protect existing sessions. Deregister targets gradually, allow the TCP deregistration delay to expire and monitor connection counts before termination. UDP has no connection handshake, so in-flight datagrams can be lost during target removal and later flows can land elsewhere.
Hybrid connectivity through AWS Direct Connect adds another failure domain: a BGP session or route change can disrupt flows while the NLB still reports healthy targets. The Direct Connect BGP troubleshooting guide provides a practical sequence for checking prefix changes and routing instability.
Keep client-IP logs and retention policies aligned with Australian privacy requirements. The Privacy Act 1988 and the Notifiable Data Breaches scheme can matter when identifiers are exposed, while financial, health and government workloads may have additional contractual residency rules. An arvo change window in Sydney followed by a Melbourne morning handover leaves time to observe errors and roll back before the next operational shift.