← Back to Blog

FinOps Architecture Tear-Down: How I Cut a Startup's AWS Bill by 40%



FinOps Architecture Tear-Down: How I Cut a Startup's AWS Bill by 40%

A few months ago, a Series A B2B SaaS startup engaged me to review their infrastructure. Aside from payroll, their largest expenditure was an AWS bill averaging $14,000 per month. They planned to hire a full-time Senior DevOps engineer at $130,000/year primarily to get spending under control.

Instead, we agreed on a 4-week freelance architectural audit and overhaul. During that month, I re-architected their Kubernetes cluster, eliminated legacy infrastructure, and reduced their monthly AWS bill to under $8,000 a 40% reduction saving over $70,000 annually without increasing permanent headcount.

Here is a detailed breakdown of the cost drivers and how we resolved them.

1. Orphaned EBS Volumes and Snapshots

Unused infrastructure frequently represents the easiest opportunity for immediate savings. In this environment, developers regularly launched EC2 instances for testing, terminated the instances when complete, but left attached EBS volumes behind.

I executed a quick Boto3 script to list available (unattached) volumes:

import boto3

ec2 = boto3.client('ec2', region_name='us-east-1') volumes = ec2.describe_volumes(Filters=[{'Name': 'status', 'Values': ['available']}])

total_wasted_gb = 0 for volume in volumes['Volumes']: print(f"Orphaned Volume: {volume['VolumeId']}, Size: {volume['Size']}GB") total_wasted_gb += volume['Size']

print(f"Total Wasted Storage: {total_wasted_gb}GB")

The script identified over 4TB of unattached EBS volumes alongside outdated RDS snapshots. Combined, they were incurring $800/month in unused storage costs. We removed them immediately.

2. Over-Provisioned Kubernetes Nodes (EKS)

The application ran on Amazon EKS utilizing static managed node groups based on m5.2xlarge instances.

After deploying kube-state-metrics and Prometheus to measure actual pod resource consumption, the data indicated that even during peak hours, cluster utilization averaged only 15% CPU and 40% RAM. The company was paying for capacity it seldom utilized.

The Solution: I replaced static node groups with Karpenter, an open-source Kubernetes node autoscaler. Karpenter provisions instances dynamically according to pending pod requests rather than rigid node pools.

apiVersion: karpenter.sh/v1beta1
kind: NodePool
metadata:
 name: default
spec:
 template:
 spec:
 requirements:
 - key: karpenter.sh/capacity-type
 operator: In
 values: ["spot", "on-demand"]
 - key: kubernetes.io/arch
 operator: In
 values: ["amd64", "arm64"]
 limits:
 cpu: 1000
 disruption:
 consolidationPolicy: WhenUnderutilized
 expireAfter: 720h

By enabling Karpenter to mix ARM64 (Graviton) instances with Spot instances for stateless workloads, compute costs decreased by 55%.

3. NAT Gateway Data Transfer Fees

NAT Gateways can silently generate substantial data processing expenses. The startup's workloads in private subnets transmitted high volumes of internal traffic primarily S3 uploads and DynamoDB queries through NAT Gateways, which AWS bills at $0.045 per GB.

I implemented VPC Gateway Endpoints for both S3 and DynamoDB. This routed internal service traffic directly across the AWS network backbone instead of traversing the NAT Gateway.

This 10-minute Terraform configuration update saved $1,200/month.

Conclusion: Targeted Audit vs. Full-Time Headcount

Startups frequently assume that managing cloud infrastructure requires a dedicated full-time DevOps hire. In practice, initial cost optimization, CI/CD pipeline configuration, and Kubernetes tuning are often discrete projects. Once automated using Terraform and GitOps, daily maintenance can be effectively managed by existing development teams.

Before creating a new engineering position for infrastructure costs, evaluate whether a targeted architectural audit can resolve bottlenecks first.