AlgoInsight

Free lesson · AWS Fundamentals

How AWS pricing actually works - the four cost levers

Easy6 min read

The Four Levers

AWS sells hundreds of services with hundreds of pricing pages, and the surface looks impenetrable. It is not. Almost every charge on an AWS bill falls into one of four categories:

  1. Compute time - something ran for a duration. EC2 instance-hours, Lambda GB-seconds, Fargate vCPU-seconds, RDS instance-hours.
  2. Storage volume × duration - something occupied space for a period. GB-months of S3, EBS, EFS, RDS storage, snapshots.
  3. Data transfer - bytes moved across a boundary that AWS charges for.
  4. Requests and operations - a countable API-level action. S3 PUTs, Lambda invocations, DynamoDB reads and writes, API Gateway calls, KMS decrypt operations.

When you look at an unfamiliar service's pricing page, sort what you see into these four buckets and the model becomes legible immediately. When you get a surprising bill, the surprise is almost always in lever 3 or lever 4 - the two that scale with behaviour rather than with provisioned size, and therefore the two nobody estimates correctly.


Lever 3 Is The One That Bites: Data Transfer

Data transfer pricing is the most consequential thing in this topic. It is charged based on the boundary a byte crosses.

Movement Charged?
Internet → AWS (inbound) Free
AWS → Internet (outbound) Charged, tiered, most expensive rate
Within the same AZ, using private IPv4 Free
Within the same AZ, using public IP or Elastic IP Charged
Between AZs in the same Region Charged - historically in both directions
Between Regions Charged, rate varies by Region pair
Through a NAT Gateway Charged per GB processed, on top of any transfer charge
Through a VPC Gateway Endpoint (S3, DynamoDB) No endpoint charge
Through a VPC Interface Endpoint (PrivateLink) Hourly charge per endpoint per AZ, plus per GB
CloudFront → Internet Charged, but usually cheaper than direct egress
graph LR
    I[Internet] -->|free| ALB[Load Balancer]
    ALB -->|charged if cross-AZ| APP[App Tier]
    APP -->|charged if cross-AZ| DB[(Database)]
    APP -->|per-GB processing charge| NAT[NAT Gateway]
    NAT -->|egress charge| I2[Internet]
    APP -->|no endpoint charge| GE[Gateway Endpoint]
    GE --> S3[(S3)]
    ALB -->|egress charge| I
This diagram traces where charges accrue along a request path. Traffic entering from the internet to a load balancer is free. Traffic from the load balancer to the application tier is charged if it crosses an Availability Zone boundary, as is traffic from the application tier to the database. Traffic from the application tier out through a NAT Gateway incurs a per-gigabyte processing charge plus an egress charge to the internet. Traffic from the application tier to S3 through a Gateway Endpoint incurs no endpoint charge. Traffic returning from the load balancer to the internet incurs an egress charge.

Warning: The NAT Gateway is the single most common source of "why is our bill this high." It charges an hourly rate per gateway and a per-GB processing fee on everything passing through - including traffic to AWS services in the same Region. A workload pulling container images or writing to S3 through NAT is paying for bytes that could travel free through a Gateway Endpoint. Check this before optimising anything else.


Commitment Models

Compute is where the pricing model offers you real choices, and the choice is a bet about how predictable your usage is.

Model Discount Commitment Interruption risk
On-Demand none (baseline) none none
Savings Plans substantial 1 or 3 years of $/hour spend none
Reserved Instances substantial 1 or 3 years of specific capacity none
Spot largest none AWS can reclaim with short notice

The practical guidance:

Tip: Savings Plans and Reserved Instances share across accounts in an AWS Organization with consolidated billing enabled. An unused commitment in one account automatically applies to matching usage in another. This is one of the strongest practical arguments for consolidated billing and a reason not to fragment your organisation across multiple payer accounts.


The Free Tier

Three distinct kinds, frequently confused:

Important: The free tier is per account, not per person, and it does not stop charges - it discounts them. Exceeding it produces a real bill silently. Set a Budget alert at a low threshold on day one of any new account. The most common expensive accident is leaving a load balancer, a NAT Gateway, an unattached Elastic IP, or a provisioned database running after an experiment; none of these are free-tier covered at typical usage.


Reading An Unfamiliar Pricing Page

Three examples showing how the four levers compose:

S3 - storage GB-month (varies by class) + requests by type (PUT costs more than GET) + retrieval fees on colder classes + data transfer out. A workload with tiny objects and heavy request volume can spend more on requests than on storage.

Lambda - requests + GB-seconds (memory allocated × duration). Allocating more memory raises the per-millisecond rate but often lowers total cost, because CPU scales with memory and the function finishes sooner. This is not intuitive and is worth measuring rather than assuming.

DynamoDB - provisioned capacity units per hour, or on-demand per request + storage GB-month + optional features (streams, backups, global tables replication). On-demand costs more per request but eliminates capacity planning; provisioned with autoscaling is cheaper at steady high volume.


Common Failure Modes

Warning: Cross-AZ chatter in a microservice mesh. Services calling each other randomly across three AZs can generate transfer charges rivalling the compute bill. Topology-aware routing keeps a request inside one AZ once it enters.

CloudWatch Logs ingestion. Charged per GB ingested, and verbose debug logging left on in production is a recurring surprise. Retention settings control storage cost, not ingestion cost - you must reduce what you emit.

Idle provisioned resources. Load balancers, NAT Gateways, provisioned RDS, unattached Elastic IPs, and unattached EBS volumes all charge whether or not anything uses them.

Snapshot accumulation. EBS and RDS snapshots are incremental but never expire on their own. Years of automated snapshots become a real line item.

Under-sized Lambda memory. Optimising for the lowest memory setting frequently increases total cost and always increases latency.


Why This Matters In An Interview

Interview: In certification exams, the phrases "most cost-effective" and "least operational overhead" are the qualifiers that decide the answer. Two options will both be technically correct; the qualifier selects between them. Train yourself to read the qualifier before the options.

In system design interviews, naming a cost implication unprompted is a strong senior signal. "I'd put a Gateway Endpoint here so the S3 traffic doesn't go through NAT" or "this is chatty across AZs, so I'd keep the request path zone-local" tells the interviewer you have operated a system, not just designed one.

Common follow-ups:

  • "How would you reduce this architecture's cost by 30%?" → Work the levers in order: eliminate idle resources, fix data transfer paths, right-size compute, then commit to Savings Plans on the remaining baseline. Do not open with Spot.
  • "Serverless is cheaper, right?" → At low and spiky volume, usually. At sustained high volume, Lambda frequently costs more than an equivalent always-on container fleet. The honest answer names the crossover.
  • "Where would you look first on a surprise bill?" → Cost Explorer grouped by service, then by usage type. Usage type is where NAT processing and data transfer become visible; service-level grouping hides them.

Practice

Exercise: Starter. Open Cost Explorer on any account and group by usage type rather than by service. Identify every line that is data transfer or NAT processing.

Intermediate. Take a Lambda function you control and measure cost and duration at three memory settings. Find the setting that minimises total cost, and note whether it is the smallest one.

Advanced. Model the monthly cost of a three-tier application at 100 requests/second and again at 10,000 requests/second, using both a serverless design and a container design. Identify the crossover point and state which assumption in your model is least reliable.


Related Topics

Back to AWS Fundamentals