Free — no signup required

Health Checks: The Heartbeat Monitor

3 min read

How Route 53 Knows Your Server Is Alive

Route 53 Health Checks are the engine behind all health-aware routing policies (Failover, Weighted, Latency, Geolocation, Multi-Value). Without Health Checks, Route 53 routes blindly — it has no idea whether your server is returning errors or timing out.

Types of Health Checks

1. Endpoint Health Checks

Route 53 sends HTTP, HTTPS, or TCP requests to a specified IP address or hostname on a configurable interval (10 or 30 seconds).

  • For HTTP/HTTPS: Route 53 checks that the response code is 2xx or 3xx, and optionally that the response body contains a specific string (up to 5,120 bytes of the response are inspected).
  • For TCP: Route 53 checks that a TCP connection can be established.

2. CloudWatch Alarm Health Checks

Instead of checking an endpoint directly, this type monitors the state of a CloudWatch Alarm. If the alarm enters the ALARM state, the Health Check turns Unhealthy.

This is powerful for checking things that aren't directly HTTP-testable:
- DynamoDB read throttles exceeding a threshold
- SQS queue depth growing beyond acceptable limits
- Custom application metrics published to CloudWatch

3. Calculated Health Checks

A parent Health Check that monitors the state of multiple child Health Checks. You define a threshold: "This parent is Healthy if at least N of M children are Healthy."

Use case: You have 5 application servers. You want failover to trigger only if 3 or more are unhealthy (not just one). Create 5 endpoint Health Checks (one per server) and one Calculated Health Check requiring at least 3 healthy children.

How Global Monitoring Works

Route 53 Health Checkers are deployed in 15+ AWS regions worldwide. All of them independently probe your endpoint. This global distribution prevents false positives from regional internet issues — if only checkers in one region report failure but all others report success, Route 53 does not mark the endpoint unhealthy.

The threshold: An endpoint is marked Unhealthy when more than 18% of health checkers report failure. This threshold is fixed and not configurable.

Monitoring private resources: Route 53 Health Checkers are on the public internet and cannot reach resources inside a VPC (private IPs, internal ALBs). To monitor private resources, use a CloudWatch Alarm Health Check: publish a metric from inside the VPC to CloudWatch, create an alarm on that metric, and attach the alarm to a Route 53 Health Check.

What to Actually Monitor

Anti-pattern: Checking GET /index.html. This only tells you the web server process is running. It doesn't tell you whether the database is connected, the cache is warm, or the application can actually serve real requests.

Best practice: Build a dedicated /health endpoint in your application that performs a shallow check of all critical dependencies:

# Example: Flask health endpoint
@app.route('/health')
def health():
    checks = {
        'database': check_db_connection(),
        'cache': check_redis_connection(),
        'downstream_api': check_payment_service()
    }

    all_healthy = all(checks.values())
    status_code = 200 if all_healthy else 500

    return jsonify(checks), status_code

If any dependency is down, the endpoint returns 500, the Health Check turns Unhealthy, and Route 53 triggers failover — even if the web server itself is running fine.

Security consideration: Protect your /health endpoint. It reveals information about your internal dependencies. At minimum, restrict it to Route 53 Health Checker IP ranges (published by AWS) using security group rules or a WAF rule.

This is one of 18 chapters

Get every chapter — Kubernetes, Terraform, SRE, distributed systems, and more — with fast daily review built in.

See pricing