What is a Load Balancer?

When your application gets real traffic, a single server becomes a single point of failure. If it crashes, everyone is down. If it gets overwhelmed, everyone is slow. A load balancer solves both problems by spreading traffic across multiple instances and automatically removing unhealthy ones from rotation.

A load balancer is a networking component that distributes incoming requests across a pool of backend servers (called a target group in AWS). It sits between your users and your application, providing a single stable entry point while managing traffic distribution, health checking, and failover behind the scenes.

L4 vs L7 Load Balancing

Load balancers operate at different layers of the network stack, and this determines what routing decisions they can make.

A Layer 4 (L4) load balancer works at the TCP/UDP transport layer. It routes connections based on IP address and port number without understanding the content of the traffic. It is extremely fast and efficient - it just forwards packets. AWS Network Load Balancer (NLB) is L4.

A Layer 7 (L7) load balancer works at the HTTP application layer. It can inspect request content and make routing decisions based on URL path, HTTP headers, hostname, query parameters, and cookies. This enables path-based routing (send /api/* to your API servers and /static/* to a CDN origin), A/B testing, and SSL termination. AWS Application Load Balancer (ALB) is L7.

AWS ALB vs NLB

Application Load Balancer (ALB) is the right choice for most web applications and APIs. It supports HTTP/1.1, HTTP/2, and WebSockets. Routing rules let you direct traffic to different target groups based on path or hostname - critical for microservices architectures where one load balancer fronts many services. ALB integrates with AWS WAF for web application firewall rules and with Cognito for authentication.

Network Load Balancer (NLB) is the right choice when you need extremely high throughput (millions of requests per second), very low latency (sub-millisecond), TCP/UDP protocols beyond HTTP, or a static IP address for whitelisting. NLB also preserves the original client source IP, which ALB may not depending on configuration.

Key Features: Health Checks, Sticky Sessions, Connection Draining

Health checks: Load balancers periodically send requests to each backend target and check the response. If a target fails consecutive health checks, it is marked unhealthy and removed from the rotation. When it recovers, it is automatically re-added. This is the mechanism that makes load-balanced architectures self-healing.

Sticky sessions: Session affinity routes all requests from a given client to the same backend. Useful for stateful applications but creates an uneven distribution and a weak point when that backend fails.

Connection draining (deregistration delay): When you remove a target from the load balancer (for a deployment, for example), connection draining keeps the target in a "draining" state for a configurable period. Existing connections are allowed to complete; new connections are not sent to that target. This enables zero-downtime deploys.

Terraform ALB Example

# ALB and target group for an HTTPS web application
resource "aws_lb" "app" {
  name               = "cloudpros-app-alb"
  internal           = false
  load_balancer_type = "application"
  security_groups    = [aws_security_group.alb.id]
  subnets            = var.public_subnet_ids

  enable_deletion_protection = true

  tags = {
    Environment = "production"
    Terraform   = "true"
  }
}

resource "aws_lb_target_group" "app" {
  name        = "cloudpros-app-tg"
  port        = 3000
  protocol    = "HTTP"
  vpc_id      = var.vpc_id
  target_type = "ip"  # use "ip" for ECS Fargate or Kubernetes pods

  health_check {
    enabled             = true
    path                = "/health"
    port                = "traffic-port"
    protocol            = "HTTP"
    matcher             = "200"
    interval            = 30
    timeout             = 5
    healthy_threshold   = 2
    unhealthy_threshold = 3
  }

  deregistration_delay = 30
}

resource "aws_lb_listener" "https" {
  load_balancer_arn = aws_lb.app.arn
  port              = 443
  protocol          = "HTTPS"
  ssl_policy        = "ELBSecurityPolicy-TLS13-1-2-2021-06"
  certificate_arn   = var.acm_certificate_arn

  default_action {
    type             = "forward"
    target_group_arn = aws_lb_target_group.app.arn
  }
}

resource "aws_lb_listener" "http_redirect" {
  load_balancer_arn = aws_lb.app.arn
  port              = 80
  protocol          = "HTTP"

  default_action {
    type = "redirect"
    redirect {
      port        = "443"
      protocol    = "HTTPS"
      status_code = "HTTP_301"
    }
  }
}

Load Balancers in Kubernetes

In Kubernetes, a Service of type LoadBalancer provisions a cloud load balancer automatically. On AWS, this creates an NLB by default (or an ALB if you use the AWS Load Balancer Controller). The Ingress resource provides more control - it creates a single ALB that routes to different Services based on hostname and path rules, which is more cost-effective than one load balancer per Service.

Using the AWS Load Balancer Controller with Terraform is the production pattern: Terraform provisions the EKS cluster and installs the controller; Kubernetes Ingress manifests then drive ALB provisioning declaratively.

Frequently Asked Questions