When implementing HTTP/2 on AWS Application Load Balancers, many developers encounter the protocol mismatch between ALB (speaking HTTP/2 to clients) and backend servers (typically configured for HTTP/1.1). The ALB automatically handles this protocol translation, but there are specific considerations:
// Sample ALB Terraform configuration showing HTTP/2 support
resource "aws_lb_listener" "https" {
load_balancer_arn = aws_lb.example.arn
port = "443"
protocol = "HTTPS"
ssl_policy = "ELBSecurityPolicy-TLS13-1-2-2021-06"
certificate_arn = aws_acm_certificate.example.arn
default_action {
type = "forward"
target_group_arn = aws_lb_target_group.example.arn
}
}
By default, AWS ALB operates in a protocol-preserving mode:
- Client → ALB: HTTP/2 (when supported by client)
- ALB → Backend: HTTP/1.1 (default behavior)
To explicitly ensure HTTP/1.1 termination at the ALB:
# AWS CLI command to verify listener protocol
aws elbv2 describe-listeners \
--load-balancer-arn arn:aws:elasticloadbalancing:us-west-2:123456789012:loadbalancer/app/my-alb/50dc6c495c0c9188
# Expected output should show HTTPS protocol without HTTP/2 enforcement
While HTTP/2 termination at ALB provides frontend benefits, the backend communication remains HTTP/1.1. Consider these metrics:
Scenario | Latency | Throughput |
---|---|---|
Full HTTP/2 | Lowest | Highest |
ALB Termination | Medium | High |
HTTP/1.1 Only | Highest | Lowest |
To verify protocol behavior:
# Curl command to check HTTP/2 support
curl -I --http2 https://your-alb-domain.com
# Nginx backend configuration example
server {
listen 80;
server_name _;
location / {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Connection "";
}
}
For teams needing more control:
- Implement CloudFront with protocol-specific behaviors
- Use ALB forwarding rules to route based on protocol
- Configure health checks to use specific protocol versions
// Sample AWS CDK configuration for protocol handling
const listener = alb.addListener('Listener', {
port: 443,
protocol: ApplicationProtocol.HTTPS,
certificates: [certificate],
sslPolicy: SslPolicy.RECOMMENDED,
open: true
});
listener.addTargets('ApplicationFleet', {
port: 80,
protocol: ApplicationProtocol.HTTP, // Explicit HTTP/1.1 to backend
targets: [asg]
});
Many teams migrating to AWS ALB face a common dilemma: they want to leverage HTTP/2's performance benefits for client connections while maintaining HTTP/1.1 compatibility for backend servers. The good news? AWS ALB natively supports this configuration.
ALBs operate as protocol translators by default. When you enable HTTP/2 on the listener (ports 443 or 80), the ALB automatically:
- Terminates HTTP/2 connections from clients
- Converts requests to HTTP/1.1 for backend servers
- Maintains HTTP/2 features like header compression for client-side communication
Here's how to set this up using AWS CLI:
aws elbv2 create-listener \ --load-balancer-arn your-alb-arn \ --protocol HTTPS \ --port 443 \ --certificates CertificateArn=your-cert-arn \ --ssl-policy ELBSecurityPolicy-TLS13-1-2-2021-06 \ --default-actions Type=forward,TargetGroupArn=your-tg-arn \ --alpn-policy HTTP2Optional
To confirm HTTP/2 termination is working:
- Client-side check: Use browser developer tools or
curl -v --http2 https://your-domain.com
- Server-side verification: Check your web server logs for HTTP/1.1 requests
While this setup works well for most use cases, be aware of:
- Header translation overhead (typically minimal)
- ALB's HTTP/2 implementation doesn't support server push
- Connection multiplexing benefits are limited to client-ALB segment
For granular control over protocol handling:
aws elbv2 modify-listener \ --listener-arn your-listener-arn \ --alpn-policy HTTP2Preferred
Available ALPN policies:
- HTTP2Only
- HTTP2Optional
(default)
- HTTP2Preferred
- None
If you encounter problems:
- Verify ACM certificate is properly attached
- Check security groups allow 443 traffic
- Confirm target group health checks pass
- Use AWS X-Ray for connection tracing