Choosing and configuring the right managed load balancer for your cloud architecture
Introduction
Both AWS and GCP offer mature, fully managed load balancing services — removing the need to run and patch your own HAProxy or NGINX fleet. But each cloud has its own naming, tiers, and quirks, and picking the wrong one can mean paying for capabilities you don't need or missing ones you do. This guide walks through the load balancing options on both platforms, when to use each, and how to configure them.
1. The Load Balancer Landscape
| Layer | AWS | GCP |
|---|---|---|
| Layer 7 (HTTP/HTTPS) | Application Load Balancer (ALB) | External/Internal HTTP(S) Load Balancer |
| Layer 4 (TCP/UDP) | Network Load Balancer (NLB) | External/Internal TCP/UDP Network Load Balancer |
| Legacy/basic | Classic Load Balancer (CLB) — legacy, avoid for new builds | (none — GCP moved fully to the above two) |
| Global anycast | Global Accelerator | Global External HTTP(S) Load Balancer (native) |
| Service mesh / internal | AWS App Mesh + NLB/ALB | Internal HTTP(S) LB + Traffic Director |
Key distinction: GCP's HTTP(S) Load Balancer is global by default — a single anycast IP can front backends in multiple regions. AWS's ALB and NLB are regional; global reach requires layering Global Accelerator or Route 53 on top.
2. AWS Load Balancing Options
Application Load Balancer (ALB)
Layer 7, HTTP/HTTPS/gRPC-aware. Best for microservices, path-based routing, and containerized workloads (ECS/EKS).
aws elbv2 create-load-balancer \
--name my-app-alb \
--subnets subnet-0123abcd subnet-0456efgh \
--security-groups sg-0789ijkl \
--scheme internet-facing \
--type application
Routing rules let you send traffic to different target groups based on path or host:
aws elbv2 create-rule \
--listener-arn <listener-arn> \
--priority 10 \
--conditions Field=path-pattern,Values='/api/*' \
--actions Type=forward,TargetGroupArn=<api-target-group-arn>
Network Load Balancer (NLB)
Layer 4, ultra-low latency, handles millions of requests per second, preserves client source IP. Best for TCP/UDP workloads, gaming, or when raw throughput matters more than content-aware routing.
aws elbv2 create-load-balancer \
--name my-tcp-nlb \
--subnets subnet-0123abcd subnet-0456efgh \
--type network \
--scheme internet-facing
Global Accelerator
Uses AWS's global network backbone and anycast IPs to route users to the nearest healthy regional endpoint (which can itself be an ALB or NLB). Useful for multi-region failover and reducing latency for globally distributed users.
aws globalaccelerator create-accelerator \
--name my-global-app \
--ip-address-type IPV4 \
--enabled
Health Checks (ALB/NLB)
aws elbv2 create-target-group \
--name my-targets \
--protocol HTTP \
--port 80 \
--vpc-id vpc-0abc123 \
--health-check-path /health \
--health-check-interval-seconds 15 \
--healthy-threshold-count 2 \
--unhealthy-threshold-count 3
3. GCP Load Balancing Options
External HTTP(S) Load Balancer (Global)
Layer 7, globally distributed via a single anycast IP, backed by Google's edge network. Best default choice for public-facing web apps and APIs.
# Create a health check
gcloud compute health-checks create http my-health-check \
--port 80 --request-path=/health
# Create a backend service
gcloud compute backend-services create my-backend-service \
--protocol=HTTP \
--health-checks=my-health-check \
--global
# Add an instance group or NEG as a backend
gcloud compute backend-services add-backend my-backend-service \
--instance-group=my-instance-group \
--instance-group-zone=us-central1-a \
--global
# Create URL map, proxy, and forwarding rule
gcloud compute url-maps create my-url-map \
--default-service=my-backend-service
gcloud compute target-http-proxies create my-http-proxy \
--url-map=my-url-map
gcloud compute forwarding-rules create my-http-rule \
--global \
--target-http-proxy=my-http-proxy \
--ports=80
Internal HTTP(S) Load Balancer
Same Layer 7 capabilities as above, but scoped to a VPC — ideal for internal microservice-to-microservice traffic within GKE or Compute Engine.
External/Internal TCP/UDP Network Load Balancer
Layer 4 pass-through balancing, preserves source IP, minimal latency overhead. Choose this for non-HTTP protocols or when you need raw packet forwarding performance.
gcloud compute forwarding-rules create my-tcp-rule \
--region=us-central1 \
--ports=443 \
--target-pool=my-target-pool
GKE-Native Load Balancing
On GKE, a standard Service of type LoadBalancer automatically provisions a GCP Network Load Balancer:
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
type: LoadBalancer
selector:
app: my-app
ports:
- port: 80
targetPort: 8080
For Layer 7 routing on GKE, an Ingress resource provisions a Global External HTTP(S) Load Balancer automatically:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-ingress
annotations:
kubernetes.io/ingress.class: "gce"
spec:
rules:
- http:
paths:
- path: /api/*
pathType: ImplementationSpecific
backend:
service:
name: api-service
port:
number: 80
4. Choosing Between AWS and GCP Options
| Your Need | AWS | GCP |
|---|---|---|
| Public HTTP(S) web app, single region | ALB | External HTTP(S) LB (regional backend, still global IP) |
| Public HTTP(S) app, multi-region, one IP | ALB + Global Accelerator | External HTTP(S) LB (global by default) |
| Raw TCP/UDP, high throughput, preserve client IP | NLB | External/Internal TCP/UDP LB |
| Internal service-to-service traffic | ALB/NLB with internal scheme |
Internal HTTP(S) or TCP/UDP LB |
| Kubernetes workloads | ALB/NLB via AWS Load Balancer Controller (EKS) | Native via GKE Ingress/Service |
| gRPC | ALB (native support) | External/Internal HTTP(S) LB (native support) |
5. Health Checks and Failover
Both platforms let you tune failure detection sensitivity — keep this in mind so a single blip doesn't remove a healthy backend, but real failures are caught quickly.
-
AWS:
--healthy-threshold-count/--unhealthy-threshold-counton target groups, plus--health-check-interval-seconds. -
GCP:
--check-intervaland--unhealthy-thresholdongcloud compute health-checks.
# GCP: tune check sensitivity
gcloud compute health-checks update http my-health-check \
--check-interval=10s \
--unhealthy-threshold=3 \
--healthy-threshold=2
Recommendation: start with a 2-failure threshold to mark unhealthy and a 2-success threshold to mark healthy again — aggressive enough to react fast, conservative enough to avoid flapping.
6. TLS Termination
Both clouds support terminating TLS at the load balancer, offloading certificate management from your application servers.
AWS (ALB with ACM certificate):
aws elbv2 create-listener \
--load-balancer-arn <alb-arn> \
--protocol HTTPS \
--port 443 \
--certificates CertificateArn=<acm-cert-arn> \
--default-actions Type=forward,TargetGroupArn=<target-group-arn>
GCP (HTTP(S) LB with Google-managed certificate):
gcloud compute ssl-certificates create my-cert \
--domains=example.com \
--global
gcloud compute target-https-proxies create my-https-proxy \
--url-map=my-url-map \
--ssl-certificates=my-cert
Both AWS Certificate Manager and Google-managed SSL certificates auto-renew, so once configured correctly this is largely maintenance-free.
Closing Thoughts
AWS and GCP take slightly different philosophies — AWS gives you regional building blocks (ALB, NLB) that you compose into a global architecture with Global Accelerator, while GCP's HTTP(S) Load Balancer is global by default. Neither is strictly better; the right choice depends on whether your traffic is HTTP-aware or raw TCP/UDP, whether you need global anycast reach, and how your workloads are deployed. Once you match the load balancer type to the traffic pattern, both platforms make the operational side — health checks, TLS, scaling — largely hands-off.
Top comments (0)