FinOps 101: How to Stop AWS From Bankrupting You
Introduction: The $10,000 Surprise
We have all heard the horror stories. A Junior Developer leaves a massive GPU instance running over the weekend. A Startup accidentally pushes a 5 Petabyte file to S3 Standard storage. A looping Lambda function triggers a billion invocations.
I have my own story. I once configured a "NAT Gateway" in a development environment. I thought it was cheap. I then ran a load test that downloaded 50TB of test data from the internet. AWS charges $0.045 per GB for NAT processing. Do the math. (Hint: My manager was not happy).
The Cloud is great because it is "Infinite." But your credit card is not Infinite.
"FinOps" sounds like a boring accounting term. It's not. FinOps is Engineering. It is the art of designing systems that are efficient. If you can architect a system that costs $100/month instead of $10,000/month, you are more valuable to the company than the 10x developer who knows 5 languages.
In this guide, we are going to look at where the money actually goes. We will learn the "Big 3" cost centers (Compute, Storage, Data Transfer) and how to slash them by 70% without sacrificing performance.
Part 1: Compute (The Low Hanging Fruit)
EC2 is usually 50% of the bill. And usually, 50% of that is wasted.
1. Right-Sizing (Stop Guessing)
Most people pick m5.large because it sounds nice.
"It has 2 CPUs, that feels safe."
But your app only uses 0.1 CPU.
The Fix: Use AWS Compute Optimizer. It looks at your CloudWatch metrics for the last 2 weeks. It tells you: "Hey, this instance is 3% utilized. Downgrade it to t3.micro." Do it.
2. Spot Instances (The 90% Discount)
AWS has spare servers sitting idle. They sell them for dirt cheap (Spot Price). The catch: AWS can take them back with a 2-minute warning.
"I can't run production on that!" Yes, you can. If you are stateless.
- Good for: Web Servers, API backends, Container Nodes (EKS), Batch processing.
- Bad for: Databases, Legacy Monoliths.
Strategy: "Spot Fleet". Tell AWS: "I need 100 vCPUs. I don't care if they are m5, c5, or r5. Just give me the cheapest ones." This makes it very unlikely that all of them will be reclaimed at once.
3. Savings Plans (The Commitment)
If you know you will be on AWS for 1 year, commit to it. Compute Savings Plan:
- Commit: "I will spend $10/hour for 1 year."
- Reward: 30-50% discount on everything up to $10/hour. Even if you switch from
t3toc6or move from Virginia to Ohio. - It is flexible. Use this instead of "Reserved Instances" (RIs).
Part 2: Storage (The Silent Killer)
Disk is cheap. Until you have 10 years of logs.
EBS Volumes (The Zombie Disks)
When you terminate an EC2 instance, the EBS volume (Hard Drive) is NOT deleted by default. It just sits there. "Available". You are paying for it. I have seen accounts with 500 "Orphaned" volumes costing thousands a month.
The Fix:
- Run a script to find all "Available" volumes.
- Snapshot them (just in case).
- Delete them.
- Update your Terraform to use
delete_on_termination = true.
S3 Lifecycle Policies
You store user uploads in S3 Standard.
After 30 days, nobody looks at them.
After 1 year, it is illegal to delete them (Compliance), but nobody accesses them.
The Policy:
- Day 0: Standard ($0.023/GB).
- Day 30: Move to Intelligent Tiering. (It automatically moves objects between Frequent and Infrequent Access based on usage).
- Day 90: Move to Glacier Instant Retrieval. (Cheap, but 50ms latency).
- Day 365: Move to Glacier Deep Archive. ($0.00099/GB - practically free).
- Catch: It takes 12 hours to retrieve a file.
Part 3: Data Transfer (The Hidden Trap)
This is where they get you.
- AWS Ingress (Data coming in): Free.
- AWS Egress (Data leaving): Expensive.
- Inter-AZ (Data moving between Availability Zones): Expensive.
The NAT Gateway Rip-Off
A NAT Gateway allows private subnets to talk to the internet. Cost: $0.045 per hour + $0.045 per GB.
Scenario: Your servers in specific private subnet download 1TB of Docker images from Docker Hub every day. That traffic goes through the NAT Gateway. You pay $45/day.
The Fix (VPC Endpoints): Create a "VPC Endpoint" for S3 and ECR (Elastic Container Registry). This creates a "Backdoor" tunnel from your VPC typically directly to AWS services. It bypasses the NAT Gateway. Cost: Free (for Gateway Endpoints like S3/DynamoDB). Cheap (for Interface Endpoints). Savings: Massive.
Part 4: Tagging Strategy (The Accountability)
"Who launched this x1e.32xlarge instance?"
"I don't know."
You cannot optimize what you cannot measure. You must enforce a Tagging Policy.
Required Tags:
Owner: (e.g., Team-Payment)Environment: (e.g., Prod, Dev, Staging)CostCenter: (e.g., 10023)
The Enforcer:
Use AWS Config or SCP (Service Control Policies).
"If a resource does not have an Owner tag, blocking the Deployment."
This sounds harsh. It is necessary.
Otherwise, you end up with a "Junkyard" account full of mystery resources that everyone is afraid to delete.
Part 5: The Cost and Usage Report (CUR)
Cost Explorer is for managers. CUR is for Engineers.
The CUR file is a massive CSV file delivered to an S3 bucket every day. It has a line item for every single hour of every single resource. It has millions of rows.
How to analyze it: Do not open it in Excel. It will crash. Ingest it into AWS Athena (SQL for S3).
Queries: "Show me the most expensive Lambda functions by Request Count." "Show me which user transferred the most data out of the NAT Gateway."
Knowing SQL is a FinOps superpower.
Part 6: Spot Instances (The Danger Zone)
We mentioned Spot earlier, but let's go deep. Spot is not just "cheap servers." It is a market.
The Rebalance Recommendation:
AWS sends a signal before the 2-minute termination warning.
It sends a "Rebalance Recommendation" causing an EventBridge event.
"Hey, the price in us-east-1a is going up. You might want to move."
Senior Move: Hook this event to a Lambda. Have the Lambda launch a new Spot instance in us-east-1b before the old one dies. This is "Proactive Capacity Rebalancing."
Spot Block (The Unicorn): Used to exist. You could buy Spot for 6 hours guaranteed. AWS killed it. Now, you must design for failure. Checkpoint your work. If you are training an AI model for 3 days, save the weights to S3 every 10 minutes. If Spot kills you, resume from the last checkpoint.
Part 7: Graviton (The ARM Revolution)
This is the easiest 20% savings you will ever get. Switch from Intel (x86) to ARM (Graviton).
m5.large(Intel) ->m6g.large(Graviton).- Cost: 20% cheaper.
- Performance: 40% better (for many workloads).
The Catch: Software compatibility.
If you use Python, Node, Java, or Go... it usually "Just Works."
If you use compiled C++ binaries or proprietary software (Oracle), it might not work.
Docker: You must build multi-arch images (docker buildx build --platform linux/amd64,linux/arm64).
Part 8: Database FinOps (RDS & DynamoDB)
RDS (Relational):
- Stop/Start: Dev databases should not run on weekends. Use "AWS Instance Scheduler" to auto-stop them on Friday at 7 PM and start them Monday at 7 AM. (Savings: ~30%).
- Storage Autoscaling: Don't provision 1TB. Provision 100GB and enable "Storage Autoscaling." It grows as you need it.
DynamoDB (NoSQL):
- On-Demand vs Provisioned:
- On-Demand: Great for unknown traffic. Pricey at scale.
- Provisioned: Cheap, but you must guess the capacity.
- The Hybrid: Use Provisioned + Auto Scaling. Set the Min/Max capacity. It follows the curve of your traffic.
Part 9: The "Hidden" Costs (CloudWatch & NAT)
CloudWatch Logs: Ingesting logs costs $0.50 per GB. Storing logs costs $0.03 per GB. I have seen companies spend more on logging the error than fixing the error. Fix:
- Don't log "INFO" in production. Only "WARN" or "ERROR".
- Set retention. Default is "Never Expire." Change it to 30 days.
EBS Snapshots: Snapshots are incremental. But if you snapshot a high-churn database every hour, you are storing petabytes of changed blocks. Fix: Use Data Lifecycle Manager (DLM). "Keep 7 daily snapshots. Keep 4 weekly snapshots." Auto-delete the rest.
Part 10: Advanced CUR Queries (Athena)
Here is the SQL to find your true enemies.
Most Expensive S3 Buckets:
SELECT line_item_resource_id, SUM(line_item_unblended_cost) as cost
FROM "cost_usage_report"
WHERE line_item_product_code = 'AmazonS3'
AND line_item_usage_type LIKE '%TimedStorage%'
GROUP BY line_item_resource_id
ORDER BY cost DESC LIMIT 10;Data Transfer Out (Who is leaking data?):
SELECT product_service_name, line_item_usage_type, SUM(line_item_unblended_cost) as cost
FROM "cost_usage_report"
WHERE line_item_usage_type LIKE '%Bytes%'
AND line_item_usage_type LIKE '%Out%'
GROUP BY product_service_name, line_item_usage_type
ORDER BY cost DESC;Part 11: The Psychology of Spending
Why is the AWS bill high? Because of FOMO (Fear Of Missing Out). Engineers are afraid that if they pick a small server, the site will crash. So they pick the biggest one. "Just to be safe."
This is "Over-provisioning." It is the enemy of FinOps.
The Solution: Trust Auto Scaling.
Proof over intuition.
Run a load test. Show the team: "Look, t3.micro handled 1000 users. We don't need c5.2xlarge."
Part 12: Expert Glossary
- Blended Rates: The average rate across all accounts in an Organization. (Confusing. Use Unblended).
- Amortized Cost: If you paid $1000 upfront for a Savings Plan, Amortization spreads that cost over 12 months ($83/month) to show true daily cost.
- Data Transfer Region to Region: The cost of moving data between US-East-1 and US-West-2.
- NAT Gateway: A router that allows private instances to talk to the internet.
- Orphaned Resource: A resource (EBS, EIP) that is not attached to anything but still costs money.
- Right-Sizing: Matching instance types to workload performance requirements.
Conclusion: Value over Cost
FinOps is not about being cheap. It is about "Unit Economics." If your AWS bill went up 100%, but your user base went up 200%, that is a victory. You became more efficient per user.
But if your bill went up 100% and your users stayed flat... you have a leak. Go find it. And kill it.