9.1 Load Balancer Types: ALB, NLB, Gateway Load Balancer, Classic
Right, so you need to get traffic into your AWS architecture. You could just point a DNS name at a single EC2 instance and pray, but we both know how that ends: with you getting paged at 3 AM when it decides to go on a spiritual retreat. Enter Elastic Load Balancing, your digital bouncer, traffic cop, and concierge all rolled into one. It’s not just about distribution; it’s about making your system resilient and intelligent. But AWS, in its infinite wisdom, offers you not one, but four main choices. Picking the right one isn’t just a technicality—it’s the difference between a smooth ride and a constant headache.
The Application Load Balancer (ALB): Your HTTP Swiss Army Knife
This is the one you’ll probably use most. The ALB operates at Layer 7 (the application layer), which is a fancy way of saying it understands the grammar of HTTP and HTTPS. It doesn’t just see a packet; it sees a GET request for /api/users with a Accept: application/json header.
This intelligence lets you do powerful things. You can route traffic based on the path (/images/* goes to one target group, /api/* goes to another), the hostname (blog.yourdomain.com vs. app.yourdomain.com), or even query parameters or headers. This is the cornerstone of modern microservices architectures. It also handles things like SSL/TLS termination offloading the cryptographic heavy lifting from your instances, and WebSockets natively.
The one “gotcha” is that it’s not a classic TCP load balancer. Its HTTP awareness means it has a little more overhead and isn’t suitable for non-HTTP traffic. But for 95% of web-related work, it’s your go-to.
Here’s a quick Terraform example to create an ALB that routes API and static traffic differently:
resource "aws_lb" "app_alb" {
name = "my-app-alb"
internal = false
load_balancer_type = "application"
security_groups = [aws_security_group.alb_sg.id]
subnets = aws_subnet.public.*.id
}
resource "aws_lb_target_group" "api_tg" {
name = "api-targets"
port = 8080
protocol = "HTTP"
vpc_id = aws_vpc.main.id
}
resource "aws_lb_target_group" "static_tg" {
name = "static-targets"
port = 80
protocol = "HTTP"
vpc_id = aws_vpc.main.id
}
resource "aws_lb_listener" "front_end" {
load_balancer_arn = aws_lb.app_alb.arn
port = "443"
protocol = "HTTPS"
ssl_policy = "ELBSecurityPolicy-2016-08"
certificate_arn = aws_acm_certificate_validation.cert.certificate_arn
default_action {
type = "forward"
target_group_arn = aws_lb_target_group.api_tg.arn
}
}
# Add a rule to route /static/* to the static target group
resource "aws_lb_listener_rule" "static" {
listener_arn = aws_lb_listener.front_end.arn
priority = 100
action {
type = "forward"
target_group_arn = aws_lb_target_group.static_tg.arn
}
condition {
path_pattern {
values = ["/static/*"]
}
}
}
The Network Load Balancer (NLB): The Performance Purist
When the ALB’s HTTP smarts are more of a hindrance than a help, you call the NLB. It operates at Layer 4 (transport layer). It’s stupid, and that’s its greatest strength. It doesn’t care if it’s HTTP, SSH, or a custom protocol you invented last Tuesday. It sees a TCP/UDP stream and forwards it, full stop.
This makes it incredibly fast (millions of requests per second with ultra-low latency) and resilient. It’s also the only load balancer that gives you a static IP address per Availability Zone, which is non-negotiable for certain legacy or third-party integrations. Use it for gaming, financial, or VoIP workloads where every millisecond counts. The main pitfall? You are now responsible for everything. SSL termination? Your job. HTTP health checks? Your job. It just passes bytes.
The Gateway Load Balancer (GWLB): The Invisible Plumbing
This one is weird, but brilliant. It’s essentially a transparent network layer (Layer 3) designed for a single purpose: to sandwich a fleet of third-party virtual appliances (think firewalls, intrusion detection systems, deep packet inspectors) into your network path without changing your routing tables.
You send all your traffic to the GWLB. It distributes it across your firewall instances, they do their inspection thing, and then the traffic magically continues on its original path. It uses the GENEVE tunneling protocol to make this happen. You don’t use this for your web apps; you use it to protect your web apps. It’s the bouncer who also has an X-ray machine and a full-body scanner.
The Classic Load Balancer (CLB): The Legacy Anchor
Ah, the Classic. The old guard. It’s like that reliable but aging tool in your garage that kinda does everything but nothing particularly well. It predates the ALB/NLB split and has quirks to prove it. It can do both Layer 4 and rudimentary Layer 7, but its Layer 7 features are clunky compared to the ALB.
AWS themselves will tell you to use the newer load balancers for greenfield projects. The only reason you’d use a CLB now is if you’re maintaining a legacy application that can’t be bothered to update its integration. It’s the load balancer equivalent of a fax machine—it still works, but you should probably have a plan to replace it.