Skip to content
AWS aws load-balancing 6 min read

ALB vs NLB vs CLB: When to Use Which

AWS gives you three flavors of Elastic Load Balancer (ELB), and picking the wrong one is one of the most common early mistakes in cloud architecture. The Application Load Balancer (ALB) understands HTTP and can route by URL. The Network Load Balancer (NLB) is a raw, ultra-fast layer 4 router. The Classic Load Balancer (CLB) is the original 2009 design that AWS now keeps only for backward compatibility. This page explains what each one does in plain English and gives you a clear rule for choosing.

The OSI layers, briefly

A load balancer sits in front of your servers and spreads incoming traffic across them. The key difference between the three types is which layer of the network they understand.

  • Layer 7 (the application layer) is where HTTP and HTTPS live. A load balancer here can read the request — the URL path, the host header, cookies — and make routing decisions based on the content.
  • Layer 4 (the transport layer) is where raw TCP (Transmission Control Protocol) and UDP (User Datagram Protocol) live. A load balancer here only sees connections and packets, not the content inside. It is faster because it does less work.

ALB works at layer 7. NLB works at layer 4. CLB straddles both but does each one worse than the dedicated modern options.

Quick comparison

FeatureALB (Application)NLB (Network)CLB (Classic)
OSI layer7 (HTTP/HTTPS)4 (TCP/UDP/TLS)4 and 7
Routing by URL path / hostYesNoNo
WebSocket / HTTP/2 / gRPCYesPass-through onlyNo
Static IP / Elastic IPNo (DNS name only)YesNo
ThroughputVery highExtreme (millions of req/s)Moderate
LatencyLowLowestHigher
Preserve client source IPVia X-Forwarded-For headerYes (native)Limited
Target typesInstance, IP, LambdaInstance, IP, ALBInstance only
Status in 2026RecommendedRecommendedLegacy / avoid

Gotcha: Tutorials and old Stack Overflow answers still create CLBs because that was the default for years. Do not pick CLB for anything new. AWS has not added features to it in a long time, and ALB/NLB cost the same or less while doing more.

When to use the ALB

Choose the ALB when you are serving HTTP or HTTPS traffic and you want smart routing. Because it reads the request, it can send /api/* to one group of servers and /images/* to another, or route different hostnames (shop.example.com vs blog.example.com) to different backends. This makes it the natural front door for web apps, REST APIs, microservices, and containers.

Use the ALB when you need:

  • Path-based or host-based routing.
  • WebSocket connections, HTTP/2, or gRPC.
  • Native integration with AWS Lambda (a serverless function) as a target.
  • Built-in user authentication via Amazon Cognito or any OpenID Connect provider.

Do not use the ALB if you need a fixed IP address, if you are serving non-HTTP protocols (like raw TCP for a database proxy or a game server using UDP), or if you need the absolute lowest latency.

When to use the NLB

Choose the NLB when you need raw speed, extreme scale, or a static IP address. The NLB can be assigned an Elastic IP (a permanent public IP address you own) per Availability Zone, which is essential when clients must allowlist a fixed IP in their firewall.

Use the NLB when you need:

  • A static IP or Elastic IP per zone.
  • Raw TCP or UDP (databases, MQTT brokers, game servers, VoIP, custom protocols).
  • Millions of low-latency connections per second, with no sudden warm-up needed.
  • The real client source IP delivered to your servers without a header.
  • TLS termination at layer 4 with very low overhead.

Do not use the NLB if your only goal is HTTP routing by path or host — it cannot read the request, so it cannot do that.

Tip: You can put an NLB in front of an ALB. The NLB gives you the static Elastic IP that clients allowlist, and it forwards to the ALB, which does the HTTP routing. This pattern is common when a partner requires a fixed IP but you still want layer 7 features.

When to use the CLB

Essentially never, for new work. The only honest reason to touch a CLB in 2026 is that you inherited one and migration is not yet scheduled. If you find one, plan to move it: HTTP-based CLBs migrate to an ALB, and TCP-based ones migrate to an NLB. AWS provides a migration wizard in the console that copies your listeners and target settings.

A simple decision path

  1. Is the traffic HTTP or HTTPS, and do you want routing by URL or host? → ALB.
  2. Do you need a static IP, raw TCP/UDP, or extreme low-latency throughput? → NLB.
  3. Neither, and you are building something new? → Still ALB as the safe default.
  4. You see CLB in a tutorial? → Ignore it; use the answer above.

Creating one — console and CLI

The creation flow is the same screen for all three; you just pick the type first.

Console steps:

  1. Open the EC2 console and choose Load Balancers in the left menu.
  2. Click Create load balancer.
  3. Pick Application Load Balancer or Network Load Balancer (the Classic option is shown but discouraged).
  4. Name it, choose internet-facing or internal, and select your VPC and at least two subnets.
  5. Configure a listener (for ALB, HTTP/HTTPS; for NLB, TCP/UDP/TLS) and attach a target group.
  6. Review and click Create load balancer.

Equivalent AWS CLI (v2):

# Create an Application Load Balancer
aws elbv2 create-load-balancer \
  --name web-alb \
  --type application \
  --subnets subnet-0a1b2c3d subnet-0e4f5a6b \
  --security-groups sg-0a1b2c3d \
  --scheme internet-facing

# Create a Network Load Balancer instead
aws elbv2 create-load-balancer \
  --name api-nlb \
  --type network \
  --subnets subnet-0a1b2c3d subnet-0e4f5a6b \
  --scheme internet-facing

Output:

{
    "LoadBalancers": [
        {
            "LoadBalancerArn": "arn:aws:elasticloadbalancing:us-east-1:123456789012:loadbalancer/app/web-alb/50dc6c495c0c9188",
            "DNSName": "web-alb-1234567890.us-east-1.elb.amazonaws.com",
            "Type": "application",
            "Scheme": "internet-facing",
            "VpcId": "vpc-0a1b2c3d",
            "State": { "Code": "provisioning" }
        }
    ]
}

Notice the ALB returns only a DNSName, never a fixed IP. If you needed a static IP, that is your signal to have used an NLB.

Cost note

In us-east-1 (2026 on-demand pricing), both the ALB and NLB charge roughly $0.0225 per hour (about $16/month) plus a usage-based capacity unit (LCU for ALB, NLCU for NLB) that bills for connections, new connections, and bandwidth. The CLB costs about the same per hour but charges a flat per-GB data fee and lacks the efficient capacity-unit model — so on real workloads it often ends up more expensive while doing less. For one small app, expect a few dollars per month beyond the base hourly charge.

Best practices

  • Default to the ALB for any HTTP/HTTPS workload; reach for the NLB only when a hard requirement (static IP, raw TCP/UDP, extreme scale) forces it.
  • Never create a new CLB; migrate existing ones to ALB (HTTP) or NLB (TCP) using the console wizard.
  • Spread every load balancer across at least two Availability Zones for resilience.
  • If a partner needs a fixed IP but you want layer 7 routing, front an ALB with an NLB carrying Elastic IPs.
  • With an ALB, read the real client IP from the X-Forwarded-For header, since the ALB terminates the connection.
  • Enable access logs and delete idle load balancers — the hourly charge accrues even with zero traffic.
Last updated June 15, 2026
Was this helpful?