open atlas
↑ Back to track
AWS, hands-on AWS · 01 · 03

Billing and cost basics

AWS bills pay-per-use across compute, storage, and data transfer — and egress is the silent killer. Match the workload to On-Demand, Reserved/Savings Plans, or Spot, and read the bill as an architecture signal.

AWS Middle ◷ 15 min
Level
FoundationsJuniorMiddleSenior

The instance bill was flat all month. Then finance forwarded a screenshot: a single line item, “Data Transfer Out — Internet,” had quietly grown to more than the EC2 fleet that produced the traffic. Nobody provisioned it, nobody approved it, and nobody saw it coming — because egress has no dashboard you stare at, no instance you can stop. The compute cost was the part everyone watched. The bill that hurt was the part nobody was looking at.

By the end of this lesson you will know which line items to watch on every AWS bill, how to match a workload to the right purchase option, and how to set up the alerts that catch a runaway egress charge before it lands in your inbox as an invoice.

Pay-per-use and the three cost dimensions

There is no flat AWS subscription. You pay for what you provision and consume, metered per service, and the total is the sum of three recurring dimensions that show up on almost every bill.

Compute time. An EC2 instance, a Lambda invocation, a Fargate task — you pay per second or per hour that capacity exists, whether or not it is doing useful work. This is the trap of idle provisioned capacity: a stopped EC2 instance costs nothing for compute, but a running one you forgot about bills 24/7. Provisioned-but-idle is the most common avoidable line item.

Storage (GB-month). A gigabyte stored for a month is the unit. S3 Standard runs roughly $0.023 per GB-month in common regions (and is designed for 11 nines — 99.999999999% — of durability, so the cost buys near-zero data-loss risk); EBS volumes, snapshots, and RDS storage are billed the same way. Storage also meters requests, not just bytes: S3 charges around $0.0004 per 1,000 GET and $0.005 per 1,000 PUT requests, so a workload making millions of tiny object reads can run up a request bill that rivals the byte storage itself. Storage is usually the predictable part of the bill — it grows slowly and you can see it coming. The catch is that storage you stop using keeps billing until you delete it: orphaned EBS volumes from terminated instances and forgotten snapshots accrue silently.

Data transfer (egress). This is the dimension that ambushes teams. The rule of thumb: ingress (data into AWS) is generally free; egress (data out to the internet) is not — commonly around $0.09 per GB for the first tier, varying by region and volume. Worse, transfer inside AWS is not free either: traffic crossing Availability Zones typically costs ~$0.01/GB each way (so ~$0.02/GB for a round trip between two services in different AZs), and cross-Region transfer runs ~$0.02/GB. A chatty microservice mesh sprawled across AZs, or a database replicating across Regions, can run up data-transfer charges that dwarf the compute generating them. Put numbers on it: a service pushing 50 TB/month of cross-AZ chatter at ~$0.02/GB round-trip is ~$1,000/month you can erase just by pinning the two services into the same AZ — pure architecture, zero feature change.

Why this works

Why is egress the silent killer and ingress free? AWS wants your data in — ingress is the on-ramp to services you’ll then pay to run. Getting data out is where they monetize, and where your architecture leaks money you can’t see on any instance dashboard. The NAT Gateway is the classic example: every private-subnet instance reaching the internet routes through it, and you pay both an hourly charge (~$0.045/hr, ~$33/month just to exist) and a per-GB data-processing charge (~$0.045/GB) on everything that flows through — on top of the egress cost if that traffic then leaves to the internet. Concretely: a fleet pulling 100 TB/month of container images and package downloads through a NAT Gateway is roughly $4,500/month in NAT processing alone — a charge that appears nowhere on any instance dashboard and is often fixed for pennies by adding a VPC Gateway Endpoint for S3 (free) so that traffic never touches the NAT. Prices quoted here are illustrative and vary by region and time — always confirm against the live pricing page.

EC2 purchase options: the price/commitment/interruption tradeoff

The same EC2 instance can cost wildly different amounts depending on how you buy it. There are three buckets, trading price against commitment and reliability.

On-Demand is the default: no commitment, pay the full rate per second/hour, start and stop whenever. It is the most expensive per hour and the most flexible — right for spiky, unpredictable, or short-lived workloads where you can’t forecast usage.

Reserved Instances / Savings Plans are a commitment for a discount. You promise 1 or 3 years of usage (Savings Plans commit to a dollars-per-hour spend; Reserved Instances to a specific instance configuration) and AWS discounts the rate — often up to ~72% off On-Demand. Right for steady, baseline, always-on workloads whose floor you can predict a year out. The risk is the commitment itself: you pay even if usage drops.

Spot sells AWS’s spare capacity at up to ~90% off On-Demand — but AWS can reclaim it with a two-minute warning whenever it needs the capacity back. Right only for fault-tolerant, interruptible work: batch jobs, CI runners, stateless workers, big-data processing that checkpoints. Wrong for anything that can’t survive sudden termination.

Real fleets blend all three: Reserved/Savings Plans cover the predictable baseline, On-Demand absorbs the variable middle, and Spot soaks up bursty interruptible load at a steep discount.

Pick the best fit

You run a stateless batch pipeline (image processing) that can resume from checkpoints and has no deadline. Which purchase option minimizes cost?

The Free Tier and its traps

New accounts get three flavors of free, and conflating them is how the trap springs. 12-month free offerings (e.g., 750 hours/month of a t2.micro/t3.micro, 5 GB of S3) expire one year after signup — then bill at full rate, often unnoticed. Always-free offerings (e.g., 1M Lambda requests/month, a slice of DynamoDB) persist but have hard caps. Trials are short-term (30–90 days) per-service freebies.

The traps are structural. Free-tier limits are per category, not a blanket “free account” — exceed 750 instance-hours by running two instances, or spill past the S3 cap, and you’re billed on the overage immediately. The 12-month clock is the big one: teams stand up a “free” demo, forget it, and twelve months later it silently converts to a paying instance running 24/7. And the Free Tier covers the service but rarely the data transfer — your free instance can still generate billable egress. Treat the Free Tier as a metered allowance with an expiry, not as “AWS is free for a year.”

Cost controls: make the bill observable before it surprises you

When you see a spike in the bill mid-month, you want a tool that already told you it was coming — not a dashboard you had to remember to open. These four instruments are your early-warning system.

You cannot manage what you can’t see, and AWS bills after the fact — so the entire game is making spend observable early. Four tools form the baseline.

AWS Budgets lets you set a spend (or usage) threshold and get alerted — by email or SNS — when actual or forecasted cost crosses it. This is your tripwire; a forecasted-overage alert catches a runaway egress charge mid-month instead of in the next invoice. Cost Explorer is the analysis surface: it breaks spend down by service, region, and time so you can answer “what grew, and when.” Cost-allocation tags let you attribute spend to teams, projects, or environments — tag everything (team, env, service) and the bill becomes a per-owner ledger instead of one opaque number. The classic billing alarm (a CloudWatch alarm on EstimatedCharges) is the simplest first line of defense for a personal or small account.

DimensionOn-DemandReserved / Savings PlansSpot
Discount vs On-Demandbaseline (0%)up to ~72%up to ~90%
Commitmentnone1 or 3 yearsnone
Interruption risknonenonereclaimed on 2-min notice
Best-fit workloadspiky, unpredictable, short-livedsteady always-on baselinefault-tolerant, interruptible batch
Quiz

An app's EC2 cost is flat, but the monthly bill jumped sharply. Where do you look first?

Quiz

You want to be warned mid-month if spend is trending past your limit, before the invoice arrives. Which tool?

Recall before you leave
  1. 01
    EC2 cost is flat but the bill spiked. Explain the most likely cause and why no instance dashboard shows it.
  2. 02
    When do you pick On-Demand vs Reserved/Savings Plans vs Spot, and what is the tradeoff axis?
Recap

AWS billing is pay-per-use with no flat subscription, and almost every bill is the sum of three dimensions: compute time (you pay for capacity that exists, so idle running instances are the most common avoidable cost), storage measured in GB-month (S3 Standard around $0.023/GB-month, predictable but orphaned volumes and snapshots linger), and data transfer — the dimension that ambushes teams, because ingress is generally free while egress to the internet runs around $0.09/GB, cross-AZ traffic costs roughly $0.01/GB each way, cross-Region costs more, and a NAT Gateway charges both hourly and per GB processed. The same EC2 instance costs very differently by purchase model: On-Demand for spiky unpredictable work, Reserved Instances or Savings Plans for a steady baseline at up to ~72% off in exchange for a 1- or 3-year commitment, and Spot for fault-tolerant interruptible batch at up to ~90% off with a two-minute reclaim risk. The Free Tier is three things — 12-month, always-free, and trials — and its traps are per-category limits, the 12-month expiry that silently converts demos to paying resources, and the fact that it rarely covers data transfer. Make spend observable before the invoice does: AWS Budgets for forecasted-cost alerts, Cost Explorer for breaking down what grew, cost-allocation tags so the bill is a per-owner ledger, and a billing alarm as the simplest tripwire. Above all, read the bill as an architecture signal — surprise charges are almost always egress, idle provisioned capacity, or a NAT Gateway nobody was watching. Now when you see an unexpected line item, you know to look at data transfer first, check for orphaned resources second, and set a forecasted-cost Budget so the next spike alerts you before the invoice does. (All prices are illustrative and vary by region and time; confirm against the live AWS pricing page.)

Practice

Start at the top. Tasks go easiest → hardest: recall a fact, apply it to a case, then a senior-level stretch. Open one, attempt it, then reveal.

recallapplystretch0 of 5 done

Something unclear?

Ask a question about this lesson. Questions are anonymous and go straight to the author to make the lesson better.

shortcuts expand
search
K
prev piece
k
next piece
j
cycle tier
t
this menu
?
sources4
expand
  1. 01
  2. 02
  3. 03
  4. 04

Trademarks belong to their respective owners. Editorial reference only.