Home / AWS

AWSHow-toAdvanced

Optimization: finding and reducing AWS data transfer costs - cross-AZ, inter-region and internet egress

Data transfer charges hide inside EC2, RDS and other service lines. Query the Cost and Usage Report by usage type to see which kind of transfer costs most, trace it to resources and flows, and fix the common causes - chatty cross-AZ tiers, needless cross-region copies and egress that should come from a CDN.

Deepak Bhardwaj3 min read

Applies toAWS Cost and Usage Report (CUR 2.0 / Data Exports) with Athena, VPC Flow Logs, EKS/ECS services, RDS/Aurora, CloudFront

1. Break down by usage type

With CUR 2.0 in Athena:

SELECT line_item_usage_type,
       product['servicecode'] AS service,
       ROUND(SUM(line_item_usage_amount), 0) AS gb,
       ROUND(SUM(line_item_unblended_cost), 2) AS cost
FROM cur2
WHERE billing_period = '2026-09'
  AND line_item_usage_type LIKE '%Bytes%'
GROUP BY 1, 2
ORDER BY cost DESC
LIMIT 30;

How to read the usage types (prefix is the region code, e.g. EUW1-):

Usage type contains Meaning
DataTransfer-Regional-Bytes Cross-AZ within a region (charged on both sides)
DataTransfer-Out-Bytes Internet egress
AWS-Out-Bytes / AWS-In-Bytes with two region codes Inter-region transfer
NatGateway-Bytes NAT processing (see the NAT Gateway post)
CloudFront-Out-Bytes / DataTransfer-Out-OBytes CDN egress

Then group the largest type by line_item_resource_id to find the resources.

2. Trace flows

VPC Flow Logs with az-id and pkt-src/dstaddr fields show which instance pairs exchange the most bytes across AZs. Map IPs to services (ENI descriptions, EKS pod IPs).

3. Cross-AZ: common causes and fixes

Cause Fix
App in AZ-a reads from RDS writer in AZ-b Accept for writes; route reads to a same-AZ reader where consistency allows
Kubernetes service traffic spread across all AZs Topology Aware Routing / trafficDistribution: PreferClose on Services (version-dependent)
Kafka/MSK consumers fetching from leaders in other AZs Rack awareness (client.rack) for follower fetching
Load balancer cross-zone traffic ALB always cross-zone (no charge for that hop); NLB cross-zone is optional and charged. Decide per NLB
Chatty microservices spread randomly Co-locate high-traffic pairs or reduce chatter (batching, caching)
Replication (databases, caches, storage clusters) Necessary for HA; check replication factor and compression

Don't "fix" cross-AZ cost by putting everything in one AZ. That gives up availability. Optimise the large, avoidable flows.

4. Inter-region

  • Cross-region replication (S3 CRR, DynamoDB global tables, Aurora Global Database): needed for DR tier 1/2, maybe not for everything.
  • Logs and metrics shipped to a central region: aggregate or filter locally first.
  • Services calling APIs in another region by accident (hard-coded endpoints). Check SDK region configs.

5. Internet egress

  • Serve downloads and static content through CloudFront. Origin-to-CloudFront transfer from AWS origins isn't charged as internet egress, and CloudFront pricing often beats direct egress.
  • Compress responses (gzip/brotli) and use efficient formats.
  • Large data sharing with partners: consider S3 Requester Pays or data exchange options.

6. Make it visible

A monthly view: data transfer cost by type and top 10 resources, with owners. Cost allocation tags on load balancers, NAT gateways and databases help attribute it.

Tip

Start with the single largest usage type and the top 3 resources in it. Data transfer optimisation is usually a few big flows, not hundreds of small ones.

Checklist

  • CUR breakdown by data transfer usage type
  • Top resources and flows identified
  • Cross-AZ: same-AZ reads, topology-aware routing, rack awareness, NLB cross-zone decided
  • Inter-region transfers justified by DR or business need
  • Internet egress via CloudFront and compression
  • Monthly data transfer view with owners