System Design Fundamentals

Cloud Pricing Models

A

Cloud Pricing Models

When Cloud Bills Surprise You

Your startup launches on AWS. The first month’s bill is $500—manageable. Three months later, you receive an invoice for $15,000, and nobody can explain why. You dive into the AWS console, confused by hundreds of services, each with multiple pricing dimensions: compute hours, storage gigabytes, API calls, data transfer, provisioned throughput. Welcome to the reality of cloud cost management.

Cloud pricing is intentionally complex by design. Cloud providers offer flexibility and granularity, but that flexibility comes with a cost learning curve. Understanding these pricing models isn’t optional—it’s fundamental to system design. Because a beautifully architected system that bankrupts your company isn’t a well-designed system at all.

This chapter bridges the performance optimization work from Chapter 20 and practical system design. You’ll learn to predict costs before they arrive, understand which pricing levers matter most, and make informed trade-offs between performance, reliability, and budget.

The Five Pricing Dimensions

Cloud pricing revolves around five core dimensions. Every service you use charges for at least one of these:

Compute: You pay for CPU and memory resources, measured by the hour (or second). An EC2 instance running for 730 hours per month costs: instance type hourly rate × hours. A Lambda function charges per invocation plus duration: $0.0000002 per invocation + $0.0000166667 per GB-second.

Storage: You pay per gigabyte per month, plus additional charges for operations. S3 Standard costs $0.023 per GB/month for storage, plus $0.0004 per 1,000 PUT requests. RDS database storage charges separately from compute. Each tier (infrequent access, archive) costs less per GB but requires higher minimum storage.

Network Transfer: Data moving out of your cloud environment (egress) costs money. Moving data between availability zones in the same region costs money. Moving data between regions costs significantly more. Moving data within the same availability zone? That’s free. This asymmetry surprises teams.

Requests and Operations: Every API call, database query, and queue message may incur charges. DynamoDB charges for read/write capacity units. Lambda charges per invocation. CloudWatch charges per million logs ingested.

Provisioned Capacity: You reserve resources in advance and pay whether you use them or not. DynamoDB provisioned capacity, RDS reserved instances, Kubernetes node pool provisioning—you commit to paying for a minimum baseline.

Here’s a typical cost breakdown for a modest web application:

ComponentCost DriverMonthly Cost
Compute (3 m5.large instances)2,190 hours × $0.096/hour$210
RDS Database (db.t3.medium)730 hours × $0.067/hour + storage$190
S3 Storage500 GB × $0.023/GB + requests$30
Data Transfer Out1 TB egress × $0.09/GB$90
NAT Gateway1.3 TB processed × $0.045/GB$59
CloudWatch Logs50 GB ingested × $0.50/GB$25
Load Balancer1 ALB × $0.0225/hour × 730 hours$16
Total Monthly$620

Notice what’s missing? You probably expected higher. Now imagine this application grows to serve 10× the traffic—most of these costs multiply.

Understanding Pay-As-You-Go vs Committed Capacity

Cloud pricing offers two fundamental models:

Pay-As-You-Go (On-Demand): You pay only for what you use, billed hourly or by operation. A Lambda function running 10 times per day costs less than one running 100 times per day. An S3 bucket with 10 GB costs less than one with 10 TB. Maximum flexibility, maximum hourly cost.

Committed Capacity (Reserved/Provisioned): You reserve resources for a term (1–3 years) and pay upfront, receiving a discount (typically 30–70%) versus on-demand rates. You pay whether you use the resources fully or not. Lower hourly cost, inflexibility, upfront capital.

This is the central tension: flexibility costs money, and commitment saves money.

For steady-state production workloads (databases, load balancers, baseline compute), commitment makes sense. For experimental features or unpredictable workloads, on-demand pricing lets you avoid waste.

The Three Clouds: AWS, GCP, Azure

All three major cloud providers use similar pricing models with different naming conventions:

ResourceAWSGCPAzure
ComputeEC2 instancesCompute EngineVirtual Machines
Reserved computeReserved InstancesCommitted Use DiscountsReserved Instances
Flexible commitmentSavings PlansCommitted Use DiscountsSavings Plans
Serverless computeLambdaCloud FunctionsAzure Functions
Relational databaseRDSCloud SQLSQL Database
NoSQLDynamoDBDatastore/FirestoreCosmos DB

Each cloud uses similar levers—you can mix on-demand and committed resources, you pay for data transfer out, managed services are more expensive per unit than self-managed equivalents.

Hidden Costs That Surprise Teams

Beyond the obvious compute, storage, and database charges, these “hidden” costs accumulate:

NAT Gateway Data Processing: If your private EC2 instances need internet access, you use a NAT Gateway. NAT Gateway charges $0.045/GB for data processed—a 1 TB/month spike costs $45. Teams often don’t realize this charge exists until reviewing bills.

Cross-AZ Traffic: Moving data between availability zones within the same region costs $0.01/GB in each direction. A distributed system with frequent cross-AZ communication can rack up surprising transfer charges.

CloudWatch Logs Ingestion: Ingesting logs costs $0.50 per GB. If your application logs 100 GB per day (very typical for production), that’s $1,500/month just for logging—often surprising to teams who thought logging was “free.”

EBS Snapshot Storage: Every EBS snapshot you create costs $0.05 per GB-month. If you take daily snapshots of a 500 GB database for disaster recovery, after 30 days you have 15 TB of snapshots stored, costing $750/month.

Idle Load Balancers: An Application Load Balancer costs $0.0225/hour whether it receives traffic or not. An idle load balancer costs $16/month—not expensive, but multiply by 20 unused load balancers across the organization, and you’re paying $320/month for infrastructure nobody uses.

Cross-Region Replication: Replicating S3 objects or RDS databases to another region doubles (or more) your storage costs and adds significant egress charges.

Did you know? AWS’s pricing calculator and cost explorer tools let you estimate costs before you build, but few teams actually use them. Most teams discover their bill through surprise.

The Free Tier Trap

AWS, GCP, and Azure all offer generous free tiers: AWS gives you 750 EC2 instance-hours per month for one year, 5 GB S3 storage free, and more. These are genuine benefits for learning.

The trap? Many services are “free up to X,” with expensive overages. CloudFront transfers 1 GB free per month, then charges per GB. DynamoDB on-demand has a free tier, then charges $1.25 per million read requests. Your experimental project that cost $0 last month might cost $200 next month when usage patterns change.

Pro tip: Set up billing alerts in your cloud console immediately. AWS lets you set email notifications when projected monthly spending exceeds a threshold. GCP and Azure offer similar features. This catches runaway costs before they become disasters.

Serverless and Managed Service Pricing

Serverless and managed services abstract away infrastructure but introduce new pricing dimensions:

Lambda: $0.0000002 per invocation + $0.0000166667 per GB-second. The math: a function that runs 100 million times per month for 1 second each, using 1 GB memory, costs: (100M × $0.0000002) + (100M × 1 second × $0.0000166667) = $20 + $1,667 = $1,687/month.

DynamoDB: On-demand mode charges $1.25 per million read requests and $6.25 per million write requests. For a write-heavy workload, this becomes expensive. Provisioned mode lets you reserve capacity (e.g., 100 write capacity units) for a fixed monthly cost ($47.50), paying per unit. The trade-off: provisioned is cheaper at scale but you pay for unused capacity.

Aurora Serverless: You pay for ACU-seconds (Aurora Capacity Units), which auto-scales based on demand. Pricing is roughly double the equivalent RDS instance, but you pay only for actual usage—no idle instances.

Managed services typically cost more per unit of compute than self-managed equivalents, but they reduce operational burden. This is a real trade-off: higher per-unit cost, lower total cost of ownership when you factor in engineering time.

Cost Planning with the Three-Tier Architecture

Let’s model a typical three-tier web application and calculate its cost:

Web Tier: 3 m5.large instances in an Auto Scaling Group, average utilization 40%.

  • On-demand: 3 × 730 hours × $0.096 = $210/month
  • Committed (1-year RI): 3 × $65/month = $195/month
  • With Savings Plan (flexible): 3 × $62/month = $186/month

Application Tier: 5 t3.large instances for background jobs.

  • Cost: 5 × 730 × $0.0832 = $304/month
  • Or 5 × $55/month with 1-year RI = $275/month

Data Tier: RDS Aurora cluster (2 db.r5.large instances), 500 GB storage.

  • Compute: 2 × 730 × $0.25 = $365/month
  • Storage: 500 × $0.10 = $50/month
  • With reserved instances: 2 × $180/month = $360/month (minimal savings here due to scale)

Storage: S3 (100 GB standard, 2 TB Glacier archive).

  • S3: 100 × $0.023 = $2.30/month
  • Glacier: 2,000 × $0.004 = $8/month

Network: Assume 10 TB egress per month (typical for a moderate API).

  • NAT Gateway: 10 × $0.045 = $450/month
  • Data transfer out: 10 × $0.09 = $900/month

Total: $210 + $304 + $365 + $50 + $10 + $1,350 = $2,289/month or about $27,500/year.

This calculation is crucial for capacity planning and budget allocation. Most teams don’t do this math until they receive their first bill.

Key Takeaways

  1. Cloud pricing is multidimensional: Compute, storage, network, requests, and provisioned capacity each have their own rate cards. You need to understand all five to predict costs accurately.

  2. The free tier is a trap: Free offerings lure you in; scaling triggers expensive charges. Set billing alerts immediately.

  3. Data transfer is hidden: Moving data out of the cloud, between regions, or between AZs costs money. This is an architectural lever for cost optimization.

  4. Managed services cost more per unit: Lambda, DynamoDB on-demand, Aurora Serverless are convenient but expensive at scale. Self-managed alternatives are cheaper but require operations effort.

  5. Commitment saves money but creates risk: Reserved instances and Savings Plans offer 30–70% discounts but lock you into specific resources. Right-size before committing.

  6. The pricing calculator is your friend: AWS, GCP, and Azure all provide cost estimation tools. Use them before launching architecture decisions.

Practice Scenarios

Scenario 1: You’re designing a photo-sharing application. Users upload photos (average 3 MB) and you store them indefinitely. You expect 1 million user signups, each uploading 50 photos over time. Calculate the annual S3 storage cost, accounting for standard and infrequent access tiers.

Scenario 2: Your microservices architecture includes a Lambda function that processes incoming events from SQS. You expect 2 million events per day, each taking 2 seconds to process and using 512 MB memory. Calculate the annual Lambda cost, and compare it to running a container on ECS.


Next: Once you understand pricing, the next step is right-sizing—matching your resource allocation to actual usage. Most teams over-provision by 50% or more, paying for capacity they never use.