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

Updated: