Back to blog
Reliability Engineering September 10, 2026

AWS Application Load Balancer (ALB) Monitoring: Target Health, Unhealthy Host Routing, and 504 Errors

Automate WhatsApp Alerts
Start Free ➔

In AWS cloud environments, the Application Load Balancer (ALB) serves as the primary Layer 7 traffic distributor across EC2 instances, ECS Fargate tasks, EKS pods, and Lambda functions. Operating within managed VPC infrastructure, ALBs handle TLS termination, HTTP/2 multiplexing, path-based routing, and target health checking. However, because ALBs sit between public internet clients and private VPC target groups, diagnosing failures requires separating proxy-level errors from origin backend degradation.

When backend targets stall, ALBs emit HTTP 504 Gateway Timeout and HTTP 502 Bad Gateway errors. If all targets in a target group fail health checks simultaneously, ALBs enter a dangerous fail-open state, routing traffic blindly to degraded nodes and magnifying outages. This engineering guide provides an SRE-level breakdown of ALB request flows, target health mechanics, 504 error diagnosis, CloudWatch telemetry, Athena access log analytics, and production incident response runbooks.


1. AWS ALB Request Flow and Failure Domains

Tracing an HTTP request through an AWS ALB reveals distinct network boundaries where failures can occur:

[Client Browser / Mobile App]
              │
              ▼ (1. Client-Side TCP & TLS Handshake)
[AWS ALB Listener (:443)]
              │
              ├── 2. Route Evaluation (Host / Path / Header Rules)
              │
              ▼
[Target Group (e.g., api-production-tg)]
              │
              ├── 3. Target Health Evaluation (HealthyHostCount vs UnHealthyHostCount)
              │
              ▼ (4. ALB-to-Target TCP Socket & HTTP Request)
[Security Group / VPC Subnet Routing]
              │
              ▼
[Target Instance / Pod (EC2, ECS, EKS :8080)] ──► [Database / Cache]

Protocol-Level Error Separation

  • Client-to-ALB Layer: Governed by HTTPCode_ELB_4XX_Count (client auth, WAF blocks) and HTTPCode_ELB_5XX_Count (proxy failures, no healthy targets, timeouts).
  • ALB-to-Target Layer: Governed by HTTPCode_Target_5XX_Count (application throws 500) and TargetResponseTime (backend latency).
  • Keep-Alive Handshake Rule: The target backend's HTTP keep-alive timeout must be strictly greater than the ALB idle timeout (default 60s). If the backend closes the TCP socket just as the ALB sends a request, the ALB returns HTTP 502 Bad Gateway.

2. Target Health States & Health Check Mechanics

ALB target groups evaluate backend instances across five distinct lifecycle states:

[Target Registered] ──► [initial] ──► (Passes HealthyThresholdCount) ──► [healthy]
                                                                            │
                                                        (Fails UnhealthyThresholdCount)
                                                                            │
                                                                            ▼
[unused] ◄── (Deregistered) ◄── [draining] ◄─────────────────────────── [unhealthy]

Target Health Check Configuration Parameters

  • HealthCheckProtocol / HealthCheckPort: Protocol (HTTP / HTTPS) and destination port.
  • HealthCheckPath: URI endpoint probed by ALB health checkers (e.g., /ready).
  • HealthCheckIntervalSeconds: Interval between consecutive checks (default: 30s, optimal: 5–10s).
  • HealthCheckTimeoutSeconds: Maximum time allowed for target to respond (default: 5s).
  • HealthyThresholdCount: Consecutive successful checks required to mark target healthy (default: 5, optimal: 2).
  • UnhealthyThresholdCount: Consecutive failed checks required to mark target unhealthy (default: 2).
  • Matcher: Expected HTTP response status codes (default: 200, optimal: 200-299).

3. The Unhealthy Host Routing Problem & The Fail-Open Trap

Understanding ALB target routing requires distinguishing partial target failure from total target group failure:

Scenario A: Partial Failure (3 of 4 Targets Healthy)
Target 1: [Healthy]   ──► Receives 33% Traffic
Target 2: [Healthy]   ──► Receives 33% Traffic
Target 3: [Healthy]   ──► Receives 33% Traffic
Target 4: [Unhealthy] ──► Receives 0% Traffic (Isolated)

Scenario B: Total Cluster Failure (0 of 4 Targets Healthy - FAIL-OPEN ACTIVATES!)
Target 1: [Unhealthy] ──► Receives 25% Traffic (Fail-Open Routing)
Target 2: [Unhealthy] ──► Receives 25% Traffic (Fail-Open Routing)
Target 3: [Unhealthy] ──► Receives 25% Traffic (Fail-Open Routing)
Target 4: [Unhealthy] ──► Receives 25% Traffic (Fail-Open Routing)

The Fail-Open Mechanism

When all targets in a target group fail health checks simultaneously, the ALB assumes its health checking mechanism is misconfigured (or that backends are under transient load) and fails open. It routes 100% of incoming production traffic across all unhealthy targets. If the targets failed due to CPU exhaustion or memory leaks, fail-open routing delivers a crushing blow, preventing any chance of backend recovery.


4. Diagnosing AWS ALB 504 Gateway Timeout Errors

An ALB-generated HTTP 504 Gateway Timeout indicates that the load balancer established a TCP connection with the target, but the target failed to return an HTTP response before the ALB Idle Timeout expired (default: 60 seconds).

[ T_{\text{request}} = T_{\text{queue}} + T_{\text{connect}} + T_{\text{target_processing}} + T_{\text{response}} > T_{\text{ALB_Idle_Timeout}} ]

Client                          ALB Ingress                           Target Backend
  │                                  │                                       │
  │── 1. GET /v1/reports ───────────►│                                       │
  │                                  │── 2. TCP SYN / ACK Established ──────►│
  │                                  │── 3. Forward GET /v1/reports ────────►│
  │                                  │                                       │
  │                                  │   [TARGET PROCESSES DEEP DATABASE QUERY]
  │                                  │   * Database lock wait: 45s
  │                                  │   * Row serialization: 20s
  │                                  │   * Total Elapsed Time: 65s
  │                                  │                                       │
  │                                  │── (t = 60.0s: Idle Timeout Breached) ─► [ALB Closes Socket]
  │◄── 4. HTTP 504 Gateway Timeout ──│                                       │

Root Causes of ALB 504 Errors

  1. Unindexed Database Queries: Application threads blocking on slow SQL execution or table locks.
  2. Thread Pool Exhaustion: Node.js event loop blocks, Python WSGI worker starvation, or Java JVM garbage collection pauses exceeding 60s.
  3. Downstream API Latency: Target synchronously awaiting third-party HTTP responses (e.g. payment gateways) without client timeouts.
  4. Security Group Ephemeral Port Drops: Network ACLs blocking return traffic from target subnets.

Use the Pingzo SLA Calculator to evaluate how 504 timeout spikes degrade your availability service level objectives.


5. SRE Operational Threshold Matrix for AWS ALB

Configure monitoring alarms in AWS CloudWatch based on actionable threshold boundaries:

CloudWatch MetricHealthy BaselineWarning StateCritical Incident (Page)Primary Investigation
UnHealthyHostCount(0)(> 0) transient(\ge 20%) of targetsInspect target logs & /ready endpoint
HTTPCode_ELB_504_Count(0\text{ / min})(1 - 5\text{ / min})(> 10\text{ / min})Slow SQL queries & worker starvation
HTTPCode_ELB_502_Count(0\text{ / min})(1 - 5\text{ / min})(> 10\text{ / min})Backend keep-alive timeout misconfiguration
TargetResponseTime (p99)(< 250\text{ ms})(250\text{ ms} - 1,500\text{ ms})(> 1,500\text{ ms})Backend CPU & database lock contention
RejectedConnectionCount(0)(> 0)(> 10\text{ / min})ALB capacity limits / security group limits
ActiveConnectionCountBaseline load(\pm 50%) spikeExtreme divergenceConnection leak / Little's Law stall

6. Athena Access Log Analytics for Root-Cause Analysis

Enable ALB Access Logs to Amazon S3 and execute Amazon Athena SQL queries to isolate failing endpoints and slow target IPs:

SELECT 
    target_status_code,
    elb_status_code,
    COUNT(*) AS total_requests,
    ROUND(AVG(target_processing_time), 3) AS avg_target_time,
    ROUND(MAX(target_processing_time), 3) AS max_target_time,
    target_ip,
    request_url
FROM alb_access_logs
WHERE parse_datetime(time,'yyyy-MM-dd''T''HH:mm:ss.SSSSSS''Z') >= NOW() - INTERVAL '1' HOUR
  AND elb_status_code = '504'
GROUP BY target_status_code, elb_status_code, target_ip, request_url
ORDER BY total_requests DESC
LIMIT 10;

Diagnostic Finding: Athena isolates that 95% of 504 errors originate from /v1/analytics/export hitting target IP 10.0.12.45 with target_processing_time = 60.001s.


7. Production AWS CLI Diagnostic Command Toolkit

Copy-pasteable CLI commands for rapid terminal incident triage:

1. Inspect Target Health Descriptions & Failure Reason Codes

aws elbv2 describe-target-health   --target-group-arn "$TARGET_GROUP_ARN"   --query 'TargetHealthDescriptions[].{TargetId:Target.Id,Port:Target.Port,State:TargetHealth.State,Reason:TargetHealth.Reason,Description:TargetHealth.Description}'   --output table
----------------------------------------------------------------------------------------------------
|                                       DescribeTargetHealth                                       |
+-------------------+-------+------------+--------------------------+------------------------------+
|    Description    | Port  |  Reason    |          State           |          TargetId            |
+-------------------+-------+------------+--------------------------+------------------------------+
| Health check 200  | 8080  | None       | healthy                  | i-0a12b34c56d78e9f0          |
| Connection timed  | 8080  | Target.    | unhealthy                | i-0f9e8d7c6b5a43210          |
|   out             |       | Timeout    |                          |                              |
+-------------------+-------+------------+--------------------------+------------------------------+

2. Probe Target Health Endpoint Directly Inside VPC

curl -sv -o /dev/null -w "Connect: %{time_connect}s | TTFB: %{time_starttransfer}s | Total: %{time_total}s | Status: %{http_code}
"   -H "Host: api.pingzo.internal"   http://10.0.12.45:8080/ready

8. CloudWatch Alarms for ALB & Target Reliability

Deploy these AWS CloudFormation / Terraform alert definitions:

Type: AWS::CloudWatch::Alarm
Properties:
  AlarmName: ALB-UnhealthyHostCount-Critical
  AlarmDescription: "More than 1 target is unhealthy in the production target group."
  MetricName: UnHealthyHostCount
  Namespace: AWS/ApplicationELB
  Statistic: Maximum
  Period: 60
  EvaluationPeriods: 2
  Threshold: 1
  ComparisonOperator: GreaterThanOrEqualToThreshold
  Dimensions:
    - Name: TargetGroup
      Value: targetgroup/production-tg/a1b2c3d4e5f6
    - Name: LoadBalancer
      Value: app/production-alb/1234567890abcdef
  AlarmActions:
    - !Ref CriticalPagerDutySNSTopic

9. Step-by-Step Incident Response Runbook: Target Health & 504 Timeouts

Follow this ordered diagnostic flow when alerted to ALB 504 errors or unhealthy targets:

  1. Classify Failure Code: Verify whether CloudWatch reports HTTPCode_ELB_504_Count (ALB idle timeout breached) or HTTPCode_Target_5XX_Count (application error).
  2. Inspect Target Health State: Run aws elbv2 describe-target-health to determine how many targets are marked unhealthy.
  3. Verify Fail-Open Condition: If HealthyHostCount == 0, the ALB has failed open. Isolate failing targets immediately.
  4. Probe Target Health Endpoint: Execute curl directly against the target IP to test if /ready returns HTTP 200 within 2 seconds.
  5. Inspect Target System Resources: Check CPU utilization, memory pressure, active database connection pools, and garbage collection pauses on target EC2/ECS hosts.
  6. Mitigate immediately:
    • If database query locks are causing 504s, kill blocking transactions in PostgreSQL/MySQL.
    • If ECS tasks or EKS pods are failing health checks, trigger an emergency autoscaling deployment to replace unhealthy instances.
    • If backends need more time for legitimate long-running tasks, temporarily increase the ALB idle timeout:
      aws elbv2 modify-load-balancer-attributes        --load-balancer-arn "$ALB_ARN"        --attributes Key=idle_timeout.timeout_seconds,Value=120
      
  7. Verify that UnHealthyHostCount returns to 0, TargetResponseTime p99 drops below 250 ms, and 504 errors cease.
  8. Document root causes in a post-mortem, establishing asynchronous worker queues and tuning backend keep-alive limits.

10. Production Hardening Checklist for AWS ALB

  • Keep-Alive Timeout Tuned: Backend server keep-alive timeout configured to 65s (strictly greater than ALB 60s idle timeout) to eliminate 502 Bad Gateways.
  • Target Health Check Tuned: HealthCheckIntervalSeconds = 10s, HealthCheckTimeoutSeconds = 3s, HealthyThresholdCount = 2, UnhealthyThresholdCount = 2.
  • Cross-Zone Load Balancing Enabled: Ensures uniform traffic distribution across all availability zones.
  • Deregistration Delay Configured: Set to 30s (instead of default 300s) for rapid container recycling during ECS/EKS deployments.
  • Access Logging Enabled: S3 access logs enabled with partitioned Athena tables for instant incident root-cause analysis.
  • Security Groups Restricted: Target security groups allow traffic only from the ALB security group ID on the application port.
  • Synthetic Canary Probing: Continuous synthetic monitors testing ALB frontend endpoints and SSL certificate expiration.

11. Operational Decision Tree

                         [AWS ALB Ingress Traffic Failure]
                                         │
                 ┌───────────────────────┴───────────────────────┐
                 ▼                                               ▼
         [HTTP 504 Gateway Timeout]                      [UnHealthyHostCount > 0]
                 │                                               │
     Check Target Processing Latency                 Inspect Target Health Reason
                 │                                               │
     ┌───────────┴───────────┐                       ┌───────────┴───────────┐
     ▼                       ▼                       ▼                       ▼
[Slow Database Queries]  [Worker Starvation]     [Health Check Timeout]  [Port Closed / Crash]
Kill Stale DB Locks      Autoscale Target Tasks  Optimize /ready Probe   Check ECS/EKS OOMKill

Related SRE & Performance Guides

Zero-Code Uptime Alerts

Stop Finding Out About Outages from Angry Users

Get instant WhatsApp & Discord alerts the second your API, website, or server goes down. Setup in 30 seconds with 60-second checks.

WhatsApp & Discord 60-Second Checks Free Forever Plan
Try Pingzo Free

Know before your users do

Connect official WhatsApp notification channels, Discord webhooks, Telegram bots, and public status pages. Start in 30 seconds.

Create Free Monitor