AWS Builder Center
Your AWS Bill Is Too High โ€” Hereโ€™s How FinOps Fixes It

Your AWS Bill Is Too High โ€” Hereโ€™s How FinOps Fixes It

๐— ๐—ผ๐˜€๐˜ ๐—ฐ๐—น๐—ผ๐˜‚๐—ฑ ๐—ฒ๐—ป๐—ด๐—ถ๐—ป๐—ฒ๐—ฒ๐—ฟ๐˜€ ๐—ณ๐—ผ๐—ฐ๐˜‚๐˜€ ๐—ผ๐—ป ๐—ฏ๐˜‚๐—ถ๐—น๐—ฑ๐—ถ๐—ป๐—ด. ๐—ก๐—ผ๐—ฏ๐—ผ๐—ฑ๐˜† ๐˜๐—ฎ๐—น๐—ธ๐˜€ ๐—ฎ๐—ฏ๐—ผ๐˜‚๐˜ ๐˜๐—ต๐—ฒ ๐—ฏ๐—ถ๐—น๐—น. ๐—จ๐—ป๐˜๐—ถ๐—น ๐—ถ๐˜'๐˜€ ๐˜๐—ผ๐—ผ ๐—น๐—ฎ๐˜๐—ฒ. ๐—™๐—ถ๐—ป๐—ข๐—ฝ๐˜€ is the practice of making every team responsible for their AWS spending โ€” ๐—ฒ๐—ป๐—ด๐—ถ๐—ป๐—ฒ๐—ฒ๐—ฟ๐—ถ๐—ป๐—ด, ๐—ณ๐—ถ๐—ป๐—ฎ๐—ป๐—ฐ๐—ฒ, ๐—ฎ๐—ป๐—ฑ ๐—ผ๐—ฝ๐˜€ ๐˜๐—ผ๐—ด๐—ฒ๐˜๐—ต๐—ฒ๐—ฟ.

A practical guide for developers, DevOps engineers, and cloud architects on optimizing AWS costs without sacrificing performance.

1. Introduction to FinOps on AWS

FinOps (Cloud Financial Operations) is the practice of bringing financial accountability to the variable spend model of cloud. It's not just about cutting costs โ€” it's about making sure every dollar spent on AWS delivers real value.
The problem? AWS makes it easy to spin up resources and hard to track what they cost. A startup can go from $500/month to $5,000/month overnight โ€” not because they grew, but because someone forgot to delete a NAT Gateway.
The FinOps triangle: Engineering + Finance + Operations
All three teams share responsibility:
  • Engineering decides what to build and how
  • Finance tracks budgets and forecasts
  • Operations monitors usage and waste
Without all three aligned, cloud bills spiral out of control.
Why AWS costs are hard to control:
  • 200+ services, each with unique pricing models
  • Data transfer costs hidden between services
  • Resources auto-provisioned by managed services
  • No hard spending limits by default

2. Understanding AWS Pricing Models

Choosing the wrong pricing model is one of the fastest ways to overspend.

Pay-As-You-Go (On-Demand)

The default. You pay for what you use, when you use it. Great for unpredictable workloads. Expensive for steady-state production systems.
Best for: Dev/test environments, unpredictable spikes, new workloads

Savings Plans

Commit to a consistent amount of compute usage ($/hour) for 1 or 3 years. Get up to 66% discount vs on-demand.
Two types:
  • Compute Savings Plans โ€” apply to EC2, Lambda, Fargate across any region/instance family
  • EC2 Instance Savings Plans โ€” deeper discount but locked to specific instance family + region
Best for: Stable production workloads with predictable usage

Reserved Instances (RIs)

Commit to a specific instance type in a specific region for 1 or 3 years. Up to 72% discount.
Best for: Databases (RDS), steady EC2 workloads, when you know exactly what you need

Spot Instances

Use AWS's spare EC2 capacity at up to 90% discount. Can be interrupted with 2-minute notice.
Best for: Batch processing, ML training, fault-tolerant workloads, Kubernetes worker nodes

Pricing Model Comparison Table

Model Discount Commitment Best Use Case On-Demand 0% None Dev/test, spikes Savings Plans Up to 66% 1-3 years Stable compute Reserved Instances Up to 72% 1-3 years Databases, steady EC2 Spot Instances Up to 90% None Batch, ML, fault-tolerant Free Tier 100% 12 months Learning, prototypes

Data Transfer Pricing โ€” The Hidden Cost

This is where most teams get surprised:
  • Data IN to AWS: Free
  • Data OUT to internet: $0.09/GB (first 10TB/month)
  • Between AZs in same region: $0.01/GB each way
  • Between regions: $0.02โ€“$0.09/GB depending on regions
A microservices architecture with 10 services talking across AZs can generate thousands of dollars in transfer costs alone.

3. AWS Cost Analysis by Service Category

Compute Services

Amazon EC2

Pricing factors:
  • Instance type (CPU, RAM, GPU)
  • Region
  • Operating system
  • Data transfer
  • EBS storage attached
Common mistakes:
  • Running oversized instances "just in case"
  • Leaving instances running 24/7 for dev/test
  • Ignoring CPU credits on T-series instances (T3 unlimited mode charges extra)
Optimization:
  • Use AWS Compute Optimizer to right-size instances
  • Schedule non-production instances to stop nights/weekends (saves ~65%)
  • Use Auto Scaling instead of always-on large instances
EC2 vs Lambda comparison:
EC2 Lambda Billing Per hour (minimum) Per 100ms + requests Cold starts No Yes (100msโ€“2s) Best for Long-running processes Event-driven, short tasks Max duration Unlimited 15 minutes Scaling Manual/Auto Scaling Automatic

AWS Lambda

Hidden costs:
  • Memory allocation affects both price AND duration
  • Provisioned concurrency charges even when idle
  • Data transfer out still applies
Optimization:
  • Right-size memory (use AWS Lambda Power Tuning tool)
  • Avoid provisioned concurrency unless you have strict latency SLAs
  • Use ARM/Graviton2 runtime โ€” 20% cheaper, often faster

ECS vs EKS

ECS EKS Control plane cost Free $0.10/hour (~$73/month) Complexity Lower Higher Flexibility AWS-native Kubernetes-native Best for AWS-first teams Multi-cloud, large orgs
Fargate vs EC2-backed containers:
Fargate is 35โ€“50% more expensive per vCPU/GB than EC2-backed. But it eliminates node management overhead. For small teams: Fargate wins on total cost (time included). For large scale: EC2 node groups with Spot wins on raw cost.

Storage Services

Amazon S3

S3 costs come from four places most people miss:
  1. Storage โ€” charged per GB per month by storage class
  2. Requests โ€” GET, PUT, LIST all cost money
  3. Data retrieval โ€” Glacier charges for retrieval
  4. Replication โ€” cross-region replication doubles storage cost
S3 Storage Classes:
Class Use Case Cost (approx) S3 Standard Frequently accessed $0.023/GB S3-IA Infrequent access $0.0125/GB S3 Glacier Instant Archives, ms retrieval $0.004/GB S3 Glacier Deep Archive Long-term archives $0.00099/GB
Optimization:
  • Enable S3 Intelligent-Tiering for unpredictable access patterns (auto-moves objects between tiers)
  • Set lifecycle policies: Standard โ†’ IA after 30 days โ†’ Glacier after 90 days
  • Enable S3 Storage Lens to identify unused buckets and request patterns
  • Delete incomplete multipart uploads (they accumulate silently)
How versioning increases costs: Every version of every object is stored and billed. A 1MB file updated daily for a year = 365MB billed. Add a lifecycle policy to expire old versions.

Amazon EBS

Hidden cost: Snapshots are charged even after the volume is deleted if you forget to clean them up.
Optimization:
  • Delete unattached volumes immediately (use AWS Config rule: ec2-volume-inuse-check)
  • Use gp3 instead of gp2 โ€” same performance, 20% cheaper, and IOPS/throughput are configurable independently
  • Set Data Lifecycle Manager to auto-delete snapshots older than N days

Database Services

RDS vs Aurora

RDS Aurora Cost Lower base cost 20% more than RDS Performance Standard Up to 5x MySQL, 3x PostgreSQL Scaling Manual Auto-scales storage Best for Simple apps, tight budgets High-traffic production
Hidden RDS costs:
  • Multi-AZ doubles instance cost
  • Read replicas are billed as full instances
  • Automated backups stored beyond retention window charge extra
  • IOPS on io1 volumes are expensive โ€” consider gp3 for most workloads

DynamoDB

Provisioned vs On-Demand:
Provisioned On-Demand Cost Lower (predictable traffic) Higher per request Risk Over/under-provision No capacity planning Best for Stable, predictable load Spiky or unknown traffic
Optimization: Use DynamoDB Reserved Capacity for provisioned mode. Up to 76% discount on read/write capacity units with 1-year commitment.

Networking Costs

NAT Gateway โ€” The Quiet Bill Killer

NAT Gateway charges:
  • $0.045/hour per gateway (~$32/month just to exist)
  • $0.045/GB of data processed
An application sending 1TB/month through NAT Gateway = $45 in data processing + $32 base = $77/month per AZ.
Alternatives:
  • Use VPC Endpoints for S3 and DynamoDB โ€” free, bypasses NAT Gateway entirely
  • Use Interface Endpoints for other AWS services โ€” cheaper than NAT for high-volume
  • For EC2 instances only accessing AWS services: remove NAT, use endpoints

CloudFront vs Direct S3/EC2

CloudFront data transfer OUT costs less than direct EC2 data transfer after 10TB/month. For public-facing apps serving media or static assets, CloudFront almost always reduces costs AND improves performance.

Public IP Charges

Since February 2024, AWS charges $0.005/hour (~$3.65/month) for every public IPv4 address, even if unused. Audit your Elastic IPs immediately โ€” any unattached EIP is pure waste.

Monitoring & Logging

CloudWatch Cost Traps

  • Custom metrics: $0.30/metric/month. A microservices app publishing 100 custom metrics = $30/month
  • Log ingestion: $0.50/GB. Verbose application logs can easily hit hundreds of GB/month
  • Log storage: $0.03/GB/month. Logs retained forever compound over time
Optimization:
  • Set log retention policies (14-30 days for most, 90 days for security/compliance)
  • Use CloudWatch Logs Insights only when needed โ€” queries are charged per GB scanned
  • Filter logs at the application level before sending to CloudWatch
  • Use EMF (Embedded Metric Format) to batch custom metrics efficiently

Security Services โ€” Cost vs Protection Tradeoffs

Service Cost What You Get GuardDuty ~$4/million events Threat detection (enable always) Security Hub $0.001/finding Unified compliance dashboard AWS Config $0.003/config item Resource change tracking WAF $5/WebACL + $1/rule/month Web application firewall Shield Standard Free Basic DDoS protection Shield Advanced $3,000/month Enterprise DDoS + 24/7 response
Recommendation: GuardDuty + Security Hub are non-negotiable for any production account. WAF is essential for public-facing APIs. Shield Advanced only if you're a high-profile target.

4. Identifying AWS Cost Leaks

These are the most common sources of silent waste:

Zombie Resources Checklist

Resource How to Find Monthly Cost Unattached EBS volumes EC2 Console โ†’ Volumes โ†’ filter "available" $0.08-0.10/GB Unattached Elastic IPs EC2 Console โ†’ Elastic IPs $3.65/IP Idle RDS instances CloudWatch โ†’ DatabaseConnections < 1 for 7 days Full instance cost Unused Load Balancers ELB Console โ†’ check RequestCount = 0 $16-22/month Old snapshots EC2 โ†’ Snapshots โ†’ sort by date $0.05/GB Stopped EC2 instances EC2 Console โ†’ filter "stopped" (EBS still charged) EBS cost Idle NAT Gateways VPC Console โ†’ NAT Gateways $32+/month

How to Detect Automatically

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# Find all unattached EBS volumes
aws ec2 describe-volumes \
--filters Name=status,Values=available \
--query 'Volumes[*].{ID:VolumeId,Size:Size,AZ:AvailabilityZone}' \
--output table

# Find unassociated Elastic IPs
aws ec2 describe-addresses \
--query 'Addresses[?AssociationId==null].{IP:PublicIp,AllocationId:AllocationId}' \
--output table

# Find RDS instances with zero connections (last 7 days)
aws cloudwatch get-metric-statistics \
--namespace AWS/RDS \
--metric-name DatabaseConnections \
--statistics Average \
--period 604800 \
--start-time $(date -d '7 days ago' +%Y-%m-%dT%H:%M:%S) \
--end-time $(date +%Y-%m-%dT%H:%M:%S)

5. AWS Cost Optimization Tools

AWS Cost Explorer

Your first stop. Visualizes spending by service, region, account, and tag. Use it to:
  • Identify top 5 cost drivers
  • Spot month-over-month anomalies
  • Get Reserved Instance recommendations

AWS Budgets

Set spending alerts before you overspend โ€” not after. Configure:
  • Monthly cost budget with 80% and 100% alerts
  • Service-specific budgets (e.g., EC2 budget: $500/month)
  • Forecast-based alerts ("you're on track to exceed budget")

AWS Compute Optimizer

Analyzes EC2, Lambda, EBS, ECS usage patterns and recommends right-sizing. Can identify instances that are 2-4x over-provisioned. Enable it โ€” it's free for basic recommendations.

Trusted Advisor

Flags low-hanging fruit automatically:
  • Underutilized EC2 instances
  • Idle load balancers
  • Unassociated Elastic IPs
  • S3 buckets with open access

Cost and Usage Reports (CUR)

The most granular cost data AWS provides. Export to S3, query with Athena, build dashboards in QuickSight. Essential for enterprise cost allocation and chargeback.

6. FinOps for Kubernetes on AWS (EKS)

EKS cost structure:
  • Control plane: $0.10/hour ($73/month) per cluster
  • Worker nodes: EC2 or Fargate pricing
  • Data transfer: Between pods across AZs

Optimization Strategies

Use Spot node groups for non-critical workloads:
1
2
3
4
5
6
7
8
9
# eksctl node group with Spot instances
nodeGroups:
- name: spot-workers
instancesDistribution:
maxPrice: 0.05
instanceTypes: ["m5.large", "m5a.large", "m4.large"]
onDemandBaseCapacity: 0
onDemandPercentageAboveBaseCapacity: 0
spotAllocationStrategy: capacity-optimized
Use Karpenter instead of Cluster Autoscaler: Karpenter provisions exactly the right instance type for pending pods in seconds, rather than scaling pre-defined node groups. Can reduce node waste by 20-40%.
Set resource requests and limits on every pod:
1
2
3
4
5
6
7
resources:
requests:
memory: "128Mi"
cpu: "250m"
limits:
memory: "256Mi"
cpu: "500m"
Without requests, the scheduler can't bin-pack efficiently โ€” you end up with half-empty nodes running at full cost.
Namespace-level cost tracking: Use tools like Kubecost or OpenCost to allocate EKS costs by namespace, team, or application.

7. FinOps Automation

Auto-Shutdown Non-Production Resources

Lambda function to stop EC2 instances outside business hours:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import boto3
import json

ec2 = boto3.client('ec2')

def lambda_handler(event, context):
# Find all instances tagged Environment=dev
response = ec2.describe_instances(
Filters=[
{'Name': 'tag:Environment', 'Values': ['dev', 'staging']},
{'Name': 'instance-state-name', 'Values': ['running']}
]
)

instance_ids = []
for reservation in response['Reservations']:
for instance in reservation['Instances']:
instance_ids.append(instance['InstanceId'])

if instance_ids:
ec2.stop_instances(InstanceIds=instance_ids)
print(f"Stopped {len(instance_ids)} dev/staging instances")

return {'stopped': instance_ids}
Schedule with EventBridge: Stop at 8pm, start at 8am weekdays. Saves ~65% on dev instance costs.

Terraform Cost Policy with Sentinel

1
2
3
4
5
6
7
8
9
10
11
12
13
# Deny expensive instance types in non-production
policy "restrict-instance-types" {
enforcement_level = "hard-mandatory"
}

main = rule {
all tfplan.resources.aws_instance as _, instances {
all instances as _, r {
r.applied.instance_type not in ["p3.16xlarge", "x1e.32xlarge"]
or r.applied.tags["Environment"] is "production"
}
}
}

8. Governance & Best Practices

Tagging Strategy โ€” The Foundation of FinOps

Without tags, you can't allocate costs to teams, projects, or environments. Define a mandatory tag schema:
1
2
3
4
5
Environment: production | staging | dev
Team: security | platform | data | frontend
Project: guardian | unmask | internal
CostCenter: eng-001 | ops-002
Owner: disha@company.com
Use AWS Config rule required-tags to enforce tagging on all resources.

Multi-Account Architecture

Account Purpose Cost Isolation Management Billing, Organizations No workloads Production Live customer workloads Strict budgets Staging Pre-production testing Moderate budgets Dev Developer sandboxes Hard spending limits Security GuardDuty, Security Hub, logs Centralized
Use AWS Organizations + SCPs to enforce guardrails across accounts (e.g., block expensive regions, require encryption).

Startup FinOps Model

  1. Enable Cost Explorer + Budgets immediately
  2. Use Free Tier aggressively for first 12 months
  3. Tag everything from day one
  4. Use Spot for all non-production
  5. Review bill weekly, not monthly

Enterprise FinOps Model

  1. Dedicated FinOps engineer or team
  2. Cost allocation via CUR + Athena + QuickSight
  3. Chargeback to business units monthly
  4. Savings Plans + RIs covering 70%+ of steady-state
  5. Automated anomaly detection with CloudWatch + SNS

9. Real-World Case Studies

Case 1: Startup Reduces AWS Bill by 70%

Before: $8,000/month
  • 20 EC2 instances (all on-demand, all running 24/7)
  • 5 RDS instances (Multi-AZ everywhere, including dev)
  • No S3 lifecycle policies
  • NAT Gateway processing 2TB/month
After: $2,400/month
  • EC2: Moved to Savings Plans + Spot for batch jobs โ†’ saved $2,800
  • RDS: Single-AZ for dev/staging, reserved 1-year for production โ†’ saved $1,200
  • S3: Intelligent-Tiering + Glacier lifecycle โ†’ saved $400
  • NAT: Replaced with VPC endpoints for S3/DynamoDB โ†’ saved $400
  • Dev instances shut down nights/weekends โ†’ saved $800

Case 2: Replacing NAT Gateway Architecture

Before:
1
2
Private EC2 โ†’ NAT Gateway โ†’ Internet โ†’ S3/DynamoDB
Cost: $32/month base + $45/TB data processed
After:
1
2
Private EC2 โ†’ VPC Endpoint โ†’ S3/DynamoDB (AWS backbone, no internet)
Cost: $0 for S3 endpoint, $0.01/GB for interface endpoints
Monthly saving for 1TB workload: $77 โ†’ $10

Case 3: S3 Lifecycle Optimization

A security platform storing CloudTrail logs: 50TB total, 48TB never accessed after 30 days.
Before: 50TB ร— $0.023 = $1,150/month After: 2TB Standard + 48TB Glacier Deep Archive = $46 + $47.5 = $93.5/month Saving: $1,056/month

10. Expensive Services vs Smarter Alternatives

Not every AWS managed service is worth the price tag. Here's when to use the premium option โ€” and when a cheaper alternative does the same job.
See content credentials

Decision Framework: When to Pay Premium

Ask these three questions before choosing the expensive option:
  1. Is this production? Dev/staging almost never needs premium services
  2. Is there a compliance requirement? If yes, the premium service may be mandatory (CloudHSM, Secrets Manager)
  3. Does the alternative hit your SLA? If the cheaper option meets your latency/availability needs, use it
Rule of thumb: Start with the cheaper alternative. Upgrade only when you hit a real, measurable limitation.

11. Common AWS FinOps Mistakes

Overengineering for scale you don't have yet Multi-AZ, read replicas, and auto-scaling on a 100-user app is expensive and unnecessary. Build for current scale, architect for future scale.
Ignoring data transfer costs Engineers focus on compute and storage. Data transfer between services, AZs, and regions silently adds 15-30% to bills.
Keeping everything "highly available" Multi-AZ RDS for a dev database costs 2x. Single-AZ with daily snapshot is fine for non-production.
No tagging strategy from day one Retroactively tagging 200 resources across 5 accounts is painful. Tag at resource creation, enforce with AWS Config.
Not using Spot instances Spot is 90% cheaper for interruptible workloads. Most batch jobs, ML training, and CI/CD pipelines can tolerate interruption with proper design.
Forgetting SageMaker notebook instances A ml.m5.xlarge notebook left running costs $120/month. Idle SageMaker endpoints are similarly expensive. Auto-shutdown notebooks after 1 hour of inactivity.

12. Future of FinOps on AWS

AI-driven cost optimization: AWS is integrating ML into Cost Explorer to predict spend and proactively recommend optimizations before waste happens.
Predictive scaling: Instead of reactive Auto Scaling, predictive scaling uses ML to provision capacity before demand spikes โ€” avoiding both over-provisioning and performance degradation.
GreenOps: AWS now provides carbon footprint dashboards per service and region. Sustainable architecture and cost-efficient architecture increasingly overlap โ€” fewer running resources means lower cost AND lower emissions.
FinOps as code: Teams are moving toward defining cost budgets and policies in code (Terraform, CDK), reviewed in pull requests alongside infrastructure changes. Cost becomes a first-class engineering concern, not an afterthought.

Cost Optimization Checklist

Immediate (do this week)

  • [ ] Enable AWS Cost Explorer
  • [ ] Set up Budget alerts (80% and 100%)
  • [ ] Audit unattached EBS volumes and Elastic IPs
  • [ ] Check for unused NAT Gateways
  • [ ] Enable GuardDuty and Security Hub

Short-term (this month)

  • [ ] Implement mandatory tagging policy
  • [ ] Switch EBS volumes from gp2 to gp3
  • [ ] Add S3 lifecycle policies to all buckets
  • [ ] Enable Compute Optimizer
  • [ ] Schedule dev/staging instance shutdown

Long-term (this quarter)

  • [ ] Evaluate Savings Plans for steady-state workloads
  • [ ] Replace NAT Gateway with VPC endpoints where possible
  • [ ] Implement Karpenter for EKS cost optimization
  • [ ] Set up CUR + Athena for detailed cost analysis
  • [ ] Build FinOps dashboard in QuickSight or Grafana

This article is part of the Explore AWS series โ€” 100 AWS services, 100 days, one cloud security lens.
Follow along on LinkedIn
#AWS #FinOps #CloudCost #CloudSecurity #DevSecOps #AWSCommunityBuilders #Devops #devsecops #cybersecurity #Developers
Any opinions in this article are those of the individual author and may not reflect the opinions of AWS.
Enjoyed reading this content? Let the author know!

Your likes, comments, shares, and saves help creators reach more builders.

Loading recommendations

Loading article