Trying Out Same-AZ-Preferred Service-to-Service Communication with ECS Service Connect's New "Zone-Aware Routing" Feature

Trying Out Same-AZ-Preferred Service-to-Service Communication with ECS Service Connect's New "Zone-Aware Routing" Feature

ECS Service Connect now supports zone-aware routing. In multi-AZ setups, service-to-service traffic prefers endpoints in the same AZ, which can cut cross-AZ data transfer costs and latency. I tested how it works.
2026.07.02

This page has been translated by machine translation. View original

Introduction

On July 1, 2026, a Zone-Aware routing feature was added to ECS Service Connect.

https://aws.amazon.com/jp/about-aws/whats-new/2026/07/ecs-service-connect-zone-aware/

This feature reduces cross-AZ data transfer costs and latency by preferentially routing requests to endpoints within the same AZ for communication between ECS services in a multi-AZ configuration.

The previous Service Connect distributed traffic evenly across all AZs using round-robin, so cross-AZ communication inevitably occurred in multi-AZ configurations. A multi-AZ configuration itself is necessary for availability, but data transfer between AZs incurs additional charges and also increases latency.

With this update, same-AZ preferential routing is enabled by default.

Item Previous Service Connect With Zone-Aware support
Routing method Round-robin (even distribution across all AZs) Same-AZ preferred
Cross-AZ data transfer Inevitably occurs in multi-AZ configurations Reduced because traffic is preferentially routed within the same AZ
Availability Automatic failover during AZ failure Same (automatically redistributes to other AZs when capacity is insufficient)
Configuration changes — Not required (enabled by default)
Application to existing services — Enabled with a single redeployment
Additional charges — None

https://docs.aws.amazon.com/AmazonECS/latest/developerguide/service-connect-zone-aware-routing.html

How It Works

Zone-Aware routing uses the zone-aware routing feature of the Service Connect proxy (Envoy sidecar).

The flow of operation is as follows.

  1. Endpoint discovery: The proxy learns all endpoints of the destination service and their AZ placement
  2. Same-AZ preference: Requests are preferentially routed to endpoints in the same AZ as the request source
  3. Residual capacity routing: Traffic that cannot fit within the same AZ is distributed based on the residual capacity of other AZs
  4. Fallback: If endpoints in the same AZ are unhealthy or insufficient, traffic is automatically routed to other AZs

Threshold Condition for Enabling

For Zone-Aware routing to be enabled, the number of endpoints of the destination service must be at least 2 × the number of AZs.

  • 2-AZ configuration: at least 4 endpoints
  • 3-AZ configuration: at least 6 endpoints

If the count falls below this threshold, it falls back to normal load balancing that does not consider AZs, and it is automatically re-enabled when the number of endpoints increases. This is a mechanism to prevent overloading a single AZ.

Comparison with Similar Concepts

Approaches that reduce cross-AZ transfer through same-AZ preference also exist in other AWS services.

Mechanism Target traffic How same-AZ preference is achieved
Regional NAT Gateway Outbound traffic AZ affinity through workload detection (dynamic)
Service Connect Zone-Aware ECS service-to-service traffic Envoy proxy weighting (dynamic)
ALB cross-zone disabling Client → target ALB node distribution setting

https://dev.classmethod.jp/articles/aws-nat-gateway-regional-availability/

Verification

I actually verified the behavior of Zone-Aware routing on a 2-AZ ECS cluster.

Verification Configuration

ECSクラスタ (Service Connect namespace: "test-sc-zone-aware")
├── サービスA (クライアント役, 2タスク)
│   ├── AZ-a: 1タスク (ECS Exec有効)
│   └── AZ-c: 1タスク (ECS Exec有効)
└── サービスB (サーバー役, 4タスク)
    ├── AZ-a: 2タスク
    └── AZ-c: 2タスク

Service B is a simple HTTP server that includes its own task's AZ information in the response. Requests are sent from Service A via Service Connect, and the AZ information in the response is used to confirm which AZ's task the request was routed to. Service B has 4 tasks in order to satisfy the threshold condition (2 × number of AZs).

Service B's App

from flask import Flask, jsonify
import requests, os

app = Flask(__name__)

@app.route("/")
def az():
    meta_uri = os.environ.get("ECS_CONTAINER_METADATA_URI_V4", "")
    if meta_uri:
        task_meta = requests.get(meta_uri + "/task", timeout=2).json()
        return jsonify({"az": task_meta.get("AvailabilityZone", "unknown")})
    return jsonify({"az": "no-metadata-uri"})

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=8080)

Service Connect Configuration

Specify name and appProtocol in the port mapping of Service B's task definition, and configure the server-side Service Connect settings when creating the service.

{
  "portMappings": [
    {
      "containerPort": 8080,
      "protocol": "tcp",
      "name": "http",
      "appProtocol": "http"
    }
  ]
}

Service Connect configuration when creating the service:

{
  "enabled": true,
  "namespace": "test-sc-zone-aware",
  "services": [
    {
      "portName": "http",
      "discoveryName": "service-b",
      "clientAliases": [
        {
          "port": 8080,
          "dnsName": "service-b"
        }
      ]
    }
  ]
}

Service A (client side) is configured in client mode only:

{
  "enabled": true,
  "namespace": "test-sc-zone-aware"
}

No additional configuration is needed for Zone-Aware routing. It is enabled by default.

Verification 1: Confirming Zone-Aware Routing Behavior

I connected to the tasks of Service A in each AZ via ECS Exec and sent 20 requests to service-b via Service Connect.

# AZ-aのタスクからリクエスト
aws ecs execute-command --cluster test-sc-zone-aware --task <task-id> \
  --container app --interactive \
  --command 'sh -c "for i in $(seq 1 20); do curl -s http://service-b:8080/; echo; done"'

Run from the task in AZ-a (ap-northeast-1a):

{"az":"ap-northeast-1a"}
{"az":"ap-northeast-1a"}
{"az":"ap-northeast-1a"}
...(以下すべて同様)

20/20 (100%) were routed to endpoints in the same AZ (ap-northeast-1a).

Run from the task in AZ-c (ap-northeast-1c):

{"az":"ap-northeast-1c"}
{"az":"ap-northeast-1c"}
{"az":"ap-northeast-1c"}
...(以下すべて同様)

Here too, 20/20 (100%) were routed to the same AZ (ap-northeast-1c). We confirmed that when endpoints are evenly distributed, 100% of requests are handled within the same AZ.

Verification 2: Confirming Fallback Behavior

I manually stopped both of Service B's tasks on the AZ-a side and checked the behavior when requests were made from a client in AZ-a.

# AZ-aのservice-bタスクを停止
aws ecs stop-task --cluster test-sc-zone-aware --task <az-a-task-id-1> --reason "test fallback"
aws ecs stop-task --cluster test-sc-zone-aware --task <az-a-task-id-2> --reason "test fallback"

Requests from Service A's task in AZ-a (executed after waiting 20 seconds following the stop):

{"az":"ap-northeast-1c"}
{"az":"ap-northeast-1c"}
{"az":"ap-northeast-1c"}
{"az":"ap-northeast-1c"}
{"az":"ap-northeast-1c"}
{"az":"ap-northeast-1c"}
{"az":"ap-northeast-1c"}
{"az":"ap-northeast-1c"}
{"az":"ap-northeast-1c"}
{"az":"ap-northeast-1c"}

10/10 (100%) were routed to AZ-c. Because no endpoints existed on the AZ-a side, all requests were sent to healthy endpoints in AZ-c.

Note that ECS launches new tasks to maintain desired-count. Once healthy endpoints exist again on the same-AZ side and the conditions for Zone-Aware routing are met, same-AZ preference resumes (the fallback behavior described in the documentation).

Supplement: Behavior Below the Threshold

For reference, here are the results of running the same test with Service B at 2 tasks (one in each AZ).

{"az":"ap-northeast-1a"}
{"az":"ap-northeast-1a"}
{"az":"ap-northeast-1c"}
{"az":"ap-northeast-1c"}
{"az":"ap-northeast-1a"}
{"az":"ap-northeast-1c"}
...(14回実行)
AZ Count Ratio
ap-northeast-1a 8 57%
ap-northeast-1c 6 43%

Requests were distributed almost evenly between AZ-a and AZ-c, and we confirmed that, at the very least, same-AZ preference behavior was not in effect. As described in the documentation, when the number of endpoints is below the threshold (2 × number of AZs = 4), the conditions for Zone-Aware routing are not met, and it falls back to normal load balancing that does not consider AZs.

Notes

I'd like to add a note about monitoring in Fargate environments.

The documentation describes how to check the state of Zone-Aware routing using Envoy statistics. The metrics used for checking are lb_zone_routing_cross_zone and lb_zone_cluster_too_small. However, this procedure assumes connecting to an EC2 instance via SSM Session Manager and running Docker exec.

In Fargate environments, the Service Connect agent container cannot be accessed directly, so I was unable to check Envoy statistics. As a way to check cross-AZ communication trends on Fargate, using VPC Flow Logs (with the az-id field) is an option.

Summary

With ECS Service Connect's Zone-Aware routing, endpoints within the same AZ are now prioritized for service-to-service communication in multi-AZ configurations. No additional configuration is required, and it is enabled by default for Service Connect services that meet the conditions.

In our verification configuration, we confirmed that with endpoints evenly placed in each AZ, 100% of requests were routed to the same AZ. Even when endpoints in the same AZ were absent, traffic was automatically fell back to healthy endpoints in another AZ.

In environments using ECS Service Connect with multiple AZs, you can expect reduced cross-AZ communication, along with lower data transfer costs and latency.

Share this article

AWSのお困り事はクラスメソッドへ