AWS BillExplained
← Topics

What EC2 actually charges for

  • Timebilled
  • Bytesbilled
  • Callsnot billed

In one line

Time and outbound bytes. Calling the API is free.

Why it works that way

EC2 has two of the three meters, and the missing one is the reason people get confused.

There is no per-call charge on the EC2 API. RunInstances, DescribeInstances, and the rest of the control plane cost nothing per invocation, no matter how often you poll them. So the number of times you ask EC2 to do something never appears on your bill.

What does appear is time — every second an instance exists — and bytes that leave.

AWS publishes the rates but never explains the asymmetry, so what follows is the standard industry account rather than anything AWS has stated. Transit and peering links are full duplex and are conventionally billed on the busier direction, and a cloud provider is overwhelmingly egress-heavy — requests arriving are small, responses leaving are large. On that reading the inbound direction is capacity already paid for and not being used, so giving it away costs close to nothing. The commercial motive needs no speculation: cheap ingress removes the barrier to moving data in, and data that has moved in earns storage and compute revenue for years. Treat the first half as a plausible mechanism and the second half as the part you can rely on.

MeterClientEC2 instanceGET /video.mp4idle200 OK — 1 GB bodyBytes1 GB × $0.09
A single HTTP exchange against an instance. The request costs nothing to receive; the response is the entire charge.

What it costs

Four lines show up for a plain instance, and only one of them is the instance:

  • Instance time. Per second with a 60-second minimum on Amazon Linux, Windows, RHEL, Ubuntu and Ubuntu Pro. Other operating systems — SUSE among them — still bill each partial hour as a full hour, so the granularity depends on the AMI you chose.
  • EBS. Provisioned GB-month, plus IOPS and throughput on the volume types that charge for them. This bills on the size you asked for, not the size you used.
  • Public IPv4. $0.005 per address-hour since 1 February 2024. An auto-assigned public address is released when you stop the instance, so that charge does stop; an Elastic IP does not, and keeps billing as PublicIPv4:IdleAddress until you release it.
  • Data transfer out. The first 100 GB per month across all AWS services is free; beyond that, roughly $0.09/GB to the internet on the first tier.

Serving 1 TB a month from an instance therefore costs about $83 in egress alone (1024 GB − 100 GB free, at $0.09), on top of whatever the instance itself costs. The egress can easily exceed the compute.

Traps

A NAT Gateway makes one gigabyte bill twice. Send traffic out through NAT and you pay the NAT hourly charge, the NAT per-GB processing charge (about $0.045/GB in most regions), and the ordinary data transfer out. AWS’s own VPC pricing page is explicit that the transfer portion is “the standard EC2 Data Transfer charge” — so the same gigabyte appears under two different services with two different names.

Processed by NAT~$0.045/GBData transfer out$0.09/GBEC2private subnetNAT Gatewayper hour + per GBInternetdestination
The same 1 GB leaving through a NAT Gateway. Three meters turn, split across two services on the bill.Bytes no charge

Cross-AZ traffic bills in both directions. Data moving between Availability Zones in one region carries the usage type <Region>-DataTransfer-Regional-Bytes, and the AWS billing documentation states that you are charged for both the inbound and outbound side — you will see two line items for a single transfer. A multi-AZ deployment buys availability, and this is its recurring price.

Stopped is not deleted. Stopping an instance stops the instance meter. The EBS volume it left behind keeps turning its own, at full provisioned size, indefinitely.