Skip to content

Cost Management

First PublishedByAtif Alam

Cloud costs can grow quickly if unmanaged. AWS provides tools for understanding, forecasting, and controlling costs. The most important practice is tagging — without tags, you can’t attribute costs to teams, projects, or environments.

The billing dashboard (Billing and Cost Management in the console) provides:

  • Month-to-date spend — Total and by-service breakdown.
  • Forecasted month-end cost — Projection based on current usage.
  • Free tier usage — Track how close you are to free tier limits.
  • Bills — Detailed monthly invoices.

First thing to do on a new account: Set up a billing alarm so you get notified before costs surprise you.

Terminal window
# Create a billing alarm (CloudWatch, us-east-1 only)
aws cloudwatch put-metric-alarm \
--alarm-name "MonthlyBillingAlarm" \
--metric-name EstimatedCharges \
--namespace AWS/Billing \
--statistic Maximum \
--period 21600 \
--threshold 100 \
--comparison-operator GreaterThanThreshold \
--evaluation-periods 1 \
--alarm-actions arn:aws:sns:us-east-1:123456789012:billing-alerts \
--dimensions Name=Currency,Value=USD \
--region us-east-1

Cost Explorer is the primary tool for analyzing AWS costs. It visualizes spend over time and lets you filter, group, and forecast.

ViewWhat It Shows
Monthly costs by serviceWhich services cost the most
Daily costsSpot spending spikes
Cost by accountIn multi-account setups (AWS Organizations)
Cost by tagCosts per team, project, environment
ForecastProjected spend for the next 3–12 months
Reservation utilizationAre your Reserved Instances being used?
  • Service — EC2, RDS, S3, Lambda, NAT Gateway, etc.
  • Region — Identify costs by region.
  • Tag — Filter by Environment=production, Team=platform, etc.
  • Instance type — See cost per EC2 instance type.
  • Usage type — Distinguish data transfer, storage, compute hours.
Terminal window
# Enable (must be done from the management account)
aws ce get-cost-and-usage \
--time-period Start=2026-02-01,End=2026-02-16 \
--granularity DAILY \
--metrics BlendedCost \
--group-by Type=DIMENSION,Key=SERVICE

Budgets let you set spending limits and receive alerts when you approach or exceed them.

TypeWhat It Tracks
Cost budgetTotal spend (e.g. “Don’t exceed $5,000/month”)
Usage budgetResource usage (e.g. “EC2 hours < 10,000”)
Reservation budgetRI/Savings Plan utilization and coverage
Savings Plans budgetSavings Plan utilization
Terminal window
aws budgets create-budget --account-id 123456789012 --budget '{
"BudgetName": "MonthlyTotal",
"BudgetLimit": {"Amount": "5000", "Unit": "USD"},
"TimeUnit": "MONTHLY",
"BudgetType": "COST"
}' --notifications-with-subscribers '[{
"Notification": {
"NotificationType": "ACTUAL",
"ComparisonOperator": "GREATER_THAN",
"Threshold": 80,
"ThresholdType": "PERCENTAGE"
},
"Subscribers": [{
"SubscriptionType": "EMAIL",
"Address": "[email protected]"
}]
}]'

This sends an email when actual spend exceeds 80% of the $5,000 budget.

Budgets can trigger automated actions when thresholds are hit:

ActionWhat It Does
Apply IAM policyDeny certain actions (e.g. block launching new EC2 instances)
Apply SCPRestrict an entire account via AWS Organizations
Notify via SNSSend to Slack, PagerDuty, custom Lambda

Tags are the foundation of cost management. Without tags, you can’t answer “which team caused this bill?”

Define a minimum set of tags that every resource must have:

Tag KeyPurposeExample Values
EnvironmentWhich environmentproduction, staging, development
TeamOwning teamplatform, backend, data
ProjectProject or productpayments, search, website
CostCenterBudget categoryengineering, marketing, R&D
ManagedByHow it was createdterraform, manual, cloudformation
MethodHow It Works
Tag policies (AWS Organizations)Define required tags and allowed values across accounts
SCPDeny resource creation without required tags
Config rulesDetect non-compliant resources after creation
TerraformEnforce tags via default_tags in the provider block
CI/CD checksLint Terraform/CloudFormation for tag compliance before apply

Terraform default tags:

provider "aws" {
region = "us-east-1"
default_tags {
tags = {
Environment = "production"
Team = "platform"
ManagedBy = "terraform"
}
}
}

Every resource created by this provider automatically gets these tags.

After defining tags, activate them as cost allocation tags in the Billing console. This makes them available in Cost Explorer and billing reports.

Terminal window
# Activate cost allocation tags
aws ce create-cost-category-definition --name "Team" \
--rules '[{"Value":"platform","Rule":{"Tags":{"Key":"Team","Values":["platform"]}}}]' \
--rule-version 1
TrapWhy It’s ExpensiveHow to Fix
Unattached EBS volumesPay for volumes not attached to any instanceAudit and delete unused volumes
Old snapshotsEBS snapshots accumulate over timeLifecycle policies, retention limits
NAT Gateway data processing$0.045/GB adds up with high trafficUse VPC endpoints for S3/DynamoDB (free)
Idle EC2 instancesRunning 24/7 but only used during business hoursAuto-stop schedules, right-size
Oversized instancesRunning m5.4xlarge when m5.large is enoughRight-size with CloudWatch metrics
Unused Elastic IPsCharged when not attached to a running instanceRelease unused EIPs
Data transfer between AZs$0.01/GB per directionMinimize cross-AZ traffic where possible
CloudWatch Logs retentionDefault is “never expire” — logs grow foreverSet retention periods (7, 30, 90 days)
Forgotten dev/test resourcesSandbox environments left runningTagging + auto-shutdown schedules

Match instance types to actual usage:

CloudWatch CPU/Memory metrics → consistently below 20%?
→ Downsize the instance type
→ Or switch to a smaller class

AWS Compute Optimizer analyzes your usage and recommends right-size changes.

OptionCommitmentFlexibilityDiscount
Reserved Instances1 or 3 years, specific instance typeLow (locked to instance family/region)Up to 72%
Compute Savings Plans1 or 3 years, dollar amountHigh (any instance type, region, OS)Up to 66%
EC2 Instance Savings Plans1 or 3 years, specific instance familyMedium (locked to family + region)Up to 72%

Rule of thumb: If an instance has been running steadily for 3+ months, it’s a candidate for a Savings Plan.

Use Spot for fault-tolerant workloads at up to 90% discount:

  • CI/CD build runners
  • Data processing / batch jobs
  • Dev/test environments
  • Kubernetes worker nodes (with mixed instance groups)
StrategySavings
S3 Intelligent-TieringAuto-moves objects to cheaper storage classes
VPC endpoints for S3/DynamoDBEliminates NAT Gateway data charges
Lambda right-sizingMore memory = faster = same or lower cost
Auto Scaling to zeroScale dev/test to 0 at night and weekends
Graviton instancesARM-based (t4g, m6g) — ~20% cheaper than x86

AWS Organizations and Multi-Account Strategy

Section titled “AWS Organizations and Multi-Account Strategy”

For larger teams, use AWS Organizations to manage multiple accounts:

Management Account (billing)
├── Production OU
│ ├── prod-app (account)
│ └── prod-data (account)
├── Development OU
│ ├── dev-app (account)
│ └── sandbox (account)
└── Security OU
└── audit (account)

Benefits:

  • Consolidated billing — One bill, volume discounts apply across all accounts.
  • SCPs — Restrict what accounts/OUs can do (e.g. block expensive instance types in dev).
  • Blast radius — A compromised dev account can’t affect production.
  • Set up billing alerts and budgets immediately — don’t wait for a surprise bill.
  • Tag everything with at least Environment, Team, and Project. Activate tags as cost allocation tags.
  • Use Cost Explorer to understand where money goes. Filter by service, tag, and region.
  • Right-size instances based on actual CloudWatch metrics. Use Compute Optimizer for recommendations.
  • Commit to Savings Plans for steady workloads (1- or 3-year). Use Spot for fault-tolerant batch work.
  • Eliminate waste: delete unused EBS volumes, set log retention, auto-stop dev environments, use VPC endpoints.
  • Use AWS Organizations for multi-account billing consolidation and SCPs for guardrails.