AWS data transfer costs arise wherever data crosses a boundary: between Availability Zones, between Regions, out to the internet, or through a NAT gateway. The bill names a usage type such as EUC1-DataTransfer-Regional-Bytes, not the application. To explain AWS data transfer costs, map each line in the Cost and Usage Report (CUR) 2.0 to a network path first, then use VPC Flow Logs to find the workload behind it.

Which network paths AWS charges for

The table lists the main paths, their CUR usage type pattern and the eu-central-1 (Frankfurt) list price. Prices are from the AWS Price List API on 10 October 2026, in USD excluding VAT, before negotiated discounts.

PathUsage type (Frankfurt)eu-central-1 list price
Out to the internetEUC1-DataTransfer-Out-BytesUSD 0.09/GB for the first 10 TB a month beyond the free allowance, tiered after that
In from the internetEUC1-DataTransfer-In-Bytesfree
Between Availability Zones, including via public or Elastic IPs inside the RegionEUC1-DataTransfer-Regional-BytesUSD 0.01/GB in each direction
Frankfurt to IrelandEUC1-EU-AWS-Out-Bytes, with a zero-cost EU-EUC1-AWS-In-Bytes counterpart in IrelandUSD 0.02/GB
NAT gateway, zonalEUC1-NatGateway-Hours, EUC1-NatGateway-BytesUSD 0.052 per hour and USD 0.052/GB processed
NAT gateway, regionalEUC1-RegionalNatGateway-Hours, EUC1-RegionalNatGateway-BytesUSD 0.052 per hour per AZ, USD 0.052/GB
Interface endpoint (PrivateLink)EUC1-VpcEndpoint-Hours, EUC1-VpcEndpoint-BytesUSD 0.012 per hour per AZ, USD 0.01/GB for the first PB
Region to CloudFront (origin fetch)EUC1-CloudFront-Out-BytesUSD 0.00/GB

Three rules from AWS's pricing pages explain most surprises. First, the free 100 GB of internet egress a month is aggregated across all services and Regions except China and GovCloud, not granted per Region. Second, transfer between S3 and EC2 in the same Region is free only while no other service sits in the path: through a NAT gateway, the gateway's data processing charge applies, as AWS's own VPC pricing example shows. Third, AWS says EU customers may request reduced data transfer rates for eligible use cases under the European Data Act through AWS Support; EU Data Act: plan cloud switching costs before 2027 covers what the Act changes.

How to read transfer lines in CUR 2.0

One byte often produces several lines, as AWS documents in "Understanding data transfer charges":

  • Between Regions there are two lines. The destination Region's -AWS-In-Bytes line carries no charge; the source Region's -AWS-Out-Bytes line carries the cost.
  • Between AZs AWS charges each metered resource for inbound and outbound traffic, so you see two DataTransfer-Regional-Bytes lines and both cost money.
  • Without a Region prefix, such as DataTransfer-Out-Bytes, the line belongs to US East (N. Virginia).
  • Ireland appears as EU in usage types and London as EUW2, so EUC1-EU-AWS-Out-Bytes is Frankfurt to Ireland.
  • CloudFront uses similar names such as EU-DataTransfer-Out-Bytes, where EU means the European edge locations. Separate it with line_item_product_code (AmazonCloudFront).
Between Regions: one transfer, two linesBetween Availability Zones: one transfer, two linesSource Region: -AWS-Out-Bytes, chargedDestination Region: -AWS-In-Bytes, no chargeSender: Regional-Bytes, chargedReceiver: Regional-Bytes, charged
One transfer, several lines: between Regions only the source's Out line costs money, between Availability Zones both resources' lines do

Alongside line_item_usage_type, use the static columns product_from_location, product_to_location, product_from_region_code and product_to_region_code. The line_item_resource_id column exists only when the export was created with the INCLUDE_RESOURCES table configuration. Still choosing an export? See AWS CUR 2.0 or FOCUS 1.2: choose the right cost export.

SQL: transfer cost by path and resource

This Athena query lists the most expensive combinations of account, service, path and resource in one billing month.

-- cur2: your Athena table for the CUR 2.0 export
SELECT
  line_item_usage_account_id,
  line_item_product_code,
  line_item_usage_type,
  product_from_location,
  product_to_location,
  line_item_resource_id,
  pricing_unit,
  ROUND(SUM(line_item_usage_amount), 2)   AS usage_amount,
  ROUND(SUM(line_item_unblended_cost), 2) AS cost
FROM cur2
WHERE bill_billing_period_start_date = TIMESTAMP '2026-09-01 00:00:00'
  AND line_item_line_item_type = 'Usage'
  AND (   line_item_usage_type LIKE '%DataTransfer%'
       OR line_item_usage_type LIKE '%-AWS-Out-Bytes'
       OR line_item_usage_type LIKE '%NatGateway%'
       OR line_item_usage_type LIKE '%VpcEndpoint%')
GROUP BY 1, 2, 3, 4, 5, 6, 7
HAVING SUM(line_item_unblended_cost) > 0
ORDER BY cost DESC
LIMIT 50;

Read the amount with its unit: NAT and endpoint lines count hours, transfer lines GB. If the table is partitioned by billing period, add that filter so Athena scans less. Discounts arrive as separate Discount lines; line_item_net_unblended_cost shows the after-discount cost and exists only when the account had a discount in the period.

Without SQL: Cost Explorer in five steps

  1. Open Cost Explorer, choose the last three closed months and monthly granularity.
  2. Under Usage type group, filter to the EC2 groups for data transfer and NAT gateways; their names start with "EC2: Data Transfer" and "EC2: NAT Gateway".
  3. Group by Usage type, then in turn by Linked account and Region.
  4. Usage type groups cover only DynamoDB, EC2, ElastiCache, RDS, Redshift and S3. For other services, filter Usage type for entries containing Bytes.
  5. For resource IDs, turn on daily resource-level data in Cost Management preferences. It covers the past 14 days and arrives within 48 hours; for longer periods, use the CUR.

Who generates the traffic: VPC Flow Logs

The bill shows which NAT gateway processed how many GB, not which instance or pod sent them. A flow log on the gateway's network interface does.

CUR line: GB processed per NAT gateway, no senderFlow log on the gateway's network interfacepkt-srcaddr: the instance or pod that sent the bytespkt-dst-aws-service: S3 or DynamoDB, a gateway endpoint could carry itaz-id: a gateway in another AZ than the sender adds Regional-Bytes
From the bill to the sender: the CUR names the gateway, the flow log on its network interface names the address, the destination service and the zone

Find the NAT gateway's network interface:

aws ec2 describe-nat-gateways --nat-gateway-ids nat-0123456789abcdef0 \
  --query 'NatGateways[].NatGatewayAddresses[].NetworkInterfaceId' --output text

Flow log with packet addresses, destination service and AZ, as Parquet in S3:

aws ec2 create-flow-logs \
  --resource-type NetworkInterface \
  --resource-ids eni-0123456789abcdef0 \
  --traffic-type ALL \
  --log-destination-type s3 \
  --log-destination arn:aws:s3:::example-flow-logs/nat/ \
  --log-format '${interface-id} ${flow-direction} ${pkt-srcaddr} ${pkt-dstaddr} ${pkt-dst-aws-service} ${az-id} ${traffic-path} ${bytes} ${start} ${end}' \
  --max-aggregation-interval 60 \
  --destination-options FileFormat=parquet,PerHourPartition=true

For a regional NAT gateway, create-flow-logs accepts the resource type RegionalNatGateway. How to read the fields:

  • pkt-srcaddr is the original private IP behind the gateway, for EKS the pod IP. Sum bytes per address and map the largest senders to instances or pods.
  • pkt-dst-aws-service showing S3 or DYNAMODB marks traffic a gateway endpoint could carry.
  • If the NAT gateway's az-id differs from the sender's subnet AZ, you also pay DataTransfer-Regional-Bytes.
  • For other paths, attach the flow log to the VPC or subnet. On egress records, traffic-path shows the route: 8 internet gateway, 7 gateway endpoint, 4 and 5 peering within or across Regions.

Flow logs carry their own vended-log charges, so limit the interface and time window. External users' IP addresses can be personal data under the GDPR; agree retention and access with your data protection owner.

Fixes and what they cost

FindingFixCost and risk
NAT bytes to S3 or DynamoDB in the same RegionGateway endpoint in the private subnets' route tablesno charge; same Region only; review the endpoint policy
NAT bytes to other AWS services such as ECR or CloudWatch LogsInterface endpoint per servicehourly charge per AZ plus per-GB charge; pays off only above break-even volume
Regional bytes between a workload and the NAT gatewayNAT gateway per AZ, or a regional NAT gatewayextra NAT hours per AZ
Regional bytes between servicesKeep traffic within the AZ, such as topology-aware routingless headroom if an AZ fails
Regional bytes over public IPs inside the RegionPrivate addresses and internal DNS namesconfiguration work
Inter-Region outFilter replication, read from the local copyrecovery and latency requirements
Internet egress from EC2, S3 or a load balancerCloudFront in front of the origin, compression, cachingCloudFront has its own prices, pay-as-you-go or flat-rate plans

For an interface endpoint, per service: it pays off when GB per month × (NAT price per GB − endpoint price per GB) exceeds number of AZs × hours in the month × endpoint price per hour. Use your contract prices, not only list prices.

Measure again and decide

Watch for displacement: lower NAT bytes alongside rising endpoint hours or regional bytes is not a saving, only a moved bill. Equally, summing volume across the zero-cost inbound lines of inter-Region traffic doubles it.

The team that owns the path decides: accept it, change the route, or change the architecture. Before the change, record the old path, the charged usage types and the expected new path; afterwards, measure the same usage types for one full billing month. In the monthly cloud cost review, that measurement belongs on the action list.

Transfer costs in Costfluent

Costfluent reads AWS cost through a read-only IAM role from a FOCUS 1.2 Data Export in your own S3 bucket (AWS integration). You can group transfer costs by account, service, Region and resource and save the view as a cost report. Cost insights show when a service grows unusually over the comparison period. Which workload creates the traffic remains a question for the flow logs in your account; Costfluent does not change network configuration.

Sources and method

Checked on 10 October 2026: AWS Data Exports: Understanding data transfer charges, CUR 2.0: Product columns, CUR 2.0: Line item columns, CUR 2.0: table configurations, Amazon VPC Pricing, Pricing for NAT gateways, Regional NAT gateways, Amazon EC2 On-Demand Pricing: Data Transfer, Amazon S3 Pricing: Data transfer, AWS PrivateLink Pricing, Gateway endpoints, Amazon CloudFront Pricing, Cost Explorer: filtering and grouping, Cost Explorer: resource-level data, Flow log records, Flow logs: pricing, AWS CLI create-flow-logs. eu-central-1 prices from the AWS Price List API: AWSDataTransfer (published 16 September 2026), AmazonEC2 (9 October 2026) and AmazonVPC (17 September 2026); CloudFront usage types from AmazonCloudFront (3 October 2026). The tables, query and review steps are Costfluent recommendations, not legal or data protection advice.