# AWS Cost Optimization and FinOps: A Practical Checklist

> How to reduce AWS costs: budgets, tagging, right-sizing, Savings Plans, NAT gateway and data transfer savings, storage lifecycle and automation with Terraform.

- Source: https://www.itwonderlab.com/aws-cost-optimization-finops/
- Published: 2026-07-30
- Updated: 2026-07-30
- Author: Javier Ruiz Jiménez (https://www.javierruizjimenez.com/)
- Site: IT Wonder Lab (https://www.itwonderlab.com/)

---

## FinOps on AWS

**FinOps** is the practice of managing cloud costs as an engineering concern: visibility first, then optimization, then continuous governance. The cloud makes it easy to create resources and easy to forget them. This checklist covers what has the greatest effect, in order.

### 1. See your costs

- Enable **Cost Explorer** and the **Cost and Usage Report** (CUR), and review the top services every month.
- Define **budgets with alerts** (AWS Budgets) per account and per project, at 50, 80 and 100 percent.
- Turn on **Cost Anomaly Detection**.
- Use a separate account per environment ([multi-account](https://www.itwonderlab.com/terraform-aws-organizations-multi-account/)), which makes costs attributable by default.

```hcl title="budget.tf"
resource "aws_budgets_budget" "monthly" {
  name         = "monthly-total"
  budget_type  = "COST"
  limit_amount = "200"
  limit_unit   = "USD"
  time_unit    = "MONTHLY"

  notification {
    comparison_operator        = "GREATER_THAN"
    threshold                  = 80
    threshold_type             = "PERCENTAGE"
    notification_type          = "ACTUAL"
    subscriber_email_addresses = ["finops@example.com"]
  }
}
```

### 2. Tag everything

Costs without tags cannot be assigned. Define mandatory tags (`Project`, `Environment`, `Owner`, `CostCenter`), apply them with the provider's `default_tags`, and activate them as **cost allocation tags** in the billing console. See [resource tagging](https://www.itwonderlab.com/aws-resource-tagging/) and [Terraform best practices](https://www.itwonderlab.com/terraform-best-practices/).

### 3. Delete what you do not use

Frequent waste:

- Unattached [EBS](https://www.itwonderlab.com/aws-ebs/) volumes and old snapshots.
- Unassociated [Elastic IPs](https://www.itwonderlab.com/aws-elastic-ip/), which are charged since all public IPv4 addresses have a cost.
- Idle load balancers and [NAT gateways](https://www.itwonderlab.com/aws-nat-gateway/) in test environments.
- Old [AMIs](https://www.itwonderlab.com/aws-ami/) with their snapshots, and [ECR](https://www.itwonderlab.com/aws-ecr/) images without a lifecycle policy.
- [CloudWatch](https://www.itwonderlab.com/aws-cloudwatch/) log groups with no retention.
- Demo environments left running: run `tofu destroy`, or schedule non-production resources to stop at night.

### 4. Right-size compute

- Use **Compute Optimizer** recommendations to find over-provisioned instances and volumes.
- Choose current generation instance types, and **Graviton (arm64)**, which usually gives better price-performance.
- Convert `gp2` volumes to `gp3`, which is cheaper and lets you set IOPS independently.
- Use [Auto Scaling](https://www.itwonderlab.com/aws-terraform-tutorial-aws-auto-scaling/) so capacity follows demand.

### 5. Choose the right purchase option

| Option | Saving | Commitment | Use for |
|---|---|---|---|
| On-demand | None | None | Unpredictable and short workloads |
| Savings Plans | Up to around 70% | 1 or 3 years of spend per hour | Steady baseline compute (EC2, Fargate, Lambda) |
| Reserved Instances | Similar | 1 or 3 years for a specific configuration | RDS, ElastiCache, OpenSearch |
| Spot | Up to around 90% | Can be interrupted | Batch jobs, CI runners, fault-tolerant workers |

Commit only to what you are sure to use for the whole period, usually 60 to 70 percent of the stable baseline.

### 6. Reduce network costs

Network charges are often a surprise:

- A NAT gateway charges per hour and per GB processed. Add free **gateway endpoints for S3 and DynamoDB**, and interface endpoints only where traffic justifies them ([VPC endpoints](https://www.itwonderlab.com/terraform-aws-vpc-endpoints/)).
- Data transfer **between Availability Zones** and **out to the Internet** costs money. Keep chatty components in the same AZ when high availability allows it, and put [CloudFront](https://www.itwonderlab.com/amazon-cloudfront/) in front of public content.
- Use a single NAT gateway for development environments only.

### 7. Storage and databases

- [S3](https://www.itwonderlab.com/aws-terraform-tutorial-aws-s3/) lifecycle rules and Intelligent-Tiering for old data. Delete incomplete multipart uploads.
- [DynamoDB](https://www.itwonderlab.com/terraform-aws-dynamodb/) TTL and on-demand mode for spiky tables.
- Stop or snapshot and delete development [RDS](https://www.itwonderlab.com/aws-rds/) instances, and consider [Aurora](https://www.itwonderlab.com/aws-aurora/) Serverless for variable loads.

### 8. Architecture

Serverless ([Lambda](https://www.itwonderlab.com/aws-lambda/), [Fargate](https://www.itwonderlab.com/aws-fargate/)) can be cheaper for irregular traffic, and more expensive for constant high load. Measure before migrating.

### 9. Automate and shift left

- Estimate the cost of every change in the pull request with [Infracost](https://www.itwonderlab.com/terraform-cost-estimation-infracost/).
- Enforce rules with [AWS Organizations SCPs](https://www.itwonderlab.com/aws-organizations/) (for example, deny very large instance types in sandbox).
- Review the top ten cost drivers every month with the people who own them.

### Quick wins in order

1. Budgets and alerts. 2. Delete idle resources. 3. Log retention. 4. Gateway endpoints. 5. `gp3` and Graviton. 6. Savings Plan for the stable base.
