AWS for DevOps — ALB vs NLB
2 minute read
12.3 — ALB vs NLB
AWS offers two main load balancers: Application Load Balancer (ALB) for HTTP/HTTPS traffic, and Network Load Balancer (NLB) for TCP/UDP traffic. Choosing the right one depends on your use case.
Comparison
| Feature |
ALB (Application) |
NLB (Network) |
| OSI Layer |
Layer 7 (HTTP/HTTPS) |
Layer 4 (TCP/UDP) |
| Protocols |
HTTP, HTTPS, gRPC |
TCP, UDP, TLS |
| Routing |
Path, host, header, query string |
Port-based |
| Performance |
Good (millions of req/s) |
Extreme (millions of packets/s) |
| Latency |
~ms |
~µs (ultra-low) |
| Static IP |
No (use Global Accelerator) |
Yes |
| WebSockets |
Yes |
Yes |
| SSL termination |
Yes |
Yes (TLS) |
| Health checks |
HTTP/HTTPS |
TCP, HTTP, HTTPS |
| Sticky sessions |
Yes |
Yes |
| Best for |
Web apps, APIs, microservices |
Gaming, IoT, financial, TCP services |
When to Use ALB
Client ──→ ALB ──→ /api/* ──→ API Service
──→ /web/* ──→ Web Service
──→ /admin/* ──→ Admin Service
──→ /health ──→ Health Check
ALB can route based on:
| Rule |
Example |
| Path |
/api/* → API target group |
| Host |
api.example.com → API, www.example.com → Web |
| Header |
X-Custom-Header: mobile → Mobile backend |
| Query string |
?version=2 → V2 target group |
| HTTP method |
POST → Write service |
# Create an ALB
$ aws elbv2 create-load-balancer \
--name my-api-alb \
--type application \
--subnets subnet-abc123 subnet-def456 \
--security-groups sg-abc123
{
"LoadBalancers": [{
"LoadBalancerArn": "arn:aws:elasticloadbalancing:...:loadbalancer/app/my-api-alb/abc123",
"DNSName": "my-api-alb-123.ap-south-1.elb.amazonaws.com",
"Type": "application"
}]
}
When to Use NLB
Client ──→ NLB (static IP) ──→ TCP:3306 ──→ Database Proxy
──→ TCP:6379 ──→ Redis Cluster
──→ TCP:9092 ──→ Kafka Brokers
# Create an NLB
$ aws elbv2 create-load-balancer \
--name my-tcp-nlb \
--type network \
--subnets subnet-abc123 subnet-def456
{
"LoadBalancers": [{
"LoadBalancerArn": "arn:aws:elasticloadbalancing:...:loadbalancer/net/my-tcp-nlb/def456",
"DNSName": "my-tcp-nlb-456.ap-south-1.elb.amazonaws.com",
"Type": "network"
}]
}
Target Groups
# Create a target group for ALB
$ aws elbv2 create-target-group \
--name api-targets \
--protocol HTTP \
--port 8080 \
--vpc-id vpc-abc123 \
--target-type ip \
--health-check-path /health \
--health-check-interval-seconds 30
# Create a target group for NLB
$ aws elbv2 create-target-group \
--name tcp-targets \
--protocol TCP \
--port 3306 \
--vpc-id vpc-abc123 \
--target-type ip \
--health-check-protocol TCP
Decision Guide
| Scenario |
Choose |
Why |
| REST API with path-based routing |
ALB |
Need Layer 7 routing |
| Microservices with different hosts |
ALB |
Host-based routing |
| gRPC services |
ALB |
Native gRPC support |
| TCP database proxy |
NLB |
TCP protocol, ultra-low latency |
| Need static IP for allowlisting |
NLB |
Static Elastic IPs |
| WebSocket application |
ALB |
WebSocket support + HTTP routing |
| IoT device connections |
NLB |
Millions of concurrent TCP connections |
| ECS Fargate services |
ALB |
Best integration with ECS |
Common Mistakes
| Mistake |
Why It Hurts |
Fix |
| Using NLB for web apps |
No path/host routing |
Use ALB for HTTP/HTTPS |
| Using ALB when you need static IP |
ALB IPs change |
Use NLB or Global Accelerator |
| No health checks |
Traffic sent to dead targets |
Always configure health checks |
| Single AZ |
No availability |
Deploy in at least 2 AZs |
Quick Reference
| Task |
Command |
| Create ALB |
aws elbv2 create-load-balancer --name NAME --type application --subnets ... --security-groups ... |
| Create NLB |
aws elbv2 create-load-balancer --name NAME --type network --subnets ... |
| Create target group |
aws elbv2 create-target-group --name NAME --protocol PROTO --port PORT --vpc-id VPC |
| Register targets |
aws elbv2 register-targets --target-group-arn ARN --targets Id=IP |
| Create listener |
aws elbv2 create-listener --load-balancer-arn ARN --protocol HTTPS --port 443 --default-actions ... |
Next → ACM Certificates