Many engineering teams spend more money on AWS than necessary. Teams often create resources for temporary testing and forget to remove them. In other cases, default configurations route internal traffic over paid public gateways.
You do not need to rewrite your application to reduce cloud expenditure. You can find and resolve five common infrastructure leaks in less than one hour.
Here is the exact procedure to identify each leak and stop unnecessary charges today.
1. Create a Free Gateway VPC Endpoint for Amazon S3
The Problem
When an application in a private subnet communicates with Amazon S3, traffic often routes through a NAT Gateway.
AWS charges:
- $0.045 per hour for each NAT Gateway instance.
- $0.045 per gigabyte of data processed through the gateway.
If your servers upload or download 4 terabytes of database backups, container images, or media files to S3 every month, you pay $180 each month in data transfer fees alone.
The Fix
AWS provides Gateway VPC Endpoints for Amazon S3 and Amazon DynamoDB at zero cost.
A Gateway Endpoint creates a direct private route inside your VPC route table. Your data stays on the AWS internal network and never touches the NAT Gateway.
How to Apply the Fix
- Open the Amazon VPC Console.
- In the navigation pane, select Endpoints, then click Create endpoint.
- Set the service category to AWS services.
- In the Services search bar, search for s3 and select the Gateway type (e.g., com.amazonaws.us-east-1.s3).
- Select your VPC and check all private Route tables.
- Select Create endpoint.
If you use Terraform, add this configuration block:
resource "aws_vpc_endpoint" "s3" {
vpc_id = var.vpc_id
service_name = "com.amazonaws.${var.aws_region}.s3"
vpc_endpoint_type = "Gateway"
route_table_ids = var.private_route_table_ids
tags = {
Name = "s3-gateway-endpoint"
}
}This change takes effect immediately. It requires no application code changes and produces zero downtime.
2. Locate and Delete Unattached EBS Volumes
The Problem
When you terminate an EC2 instance, the attached root volume terminates automatically by default. However, secondary EBS data volumes often remain active.
These unattached volumes remain in the available state. AWS continues to bill you for provisioned storage every hour, even when no virtual machine connects to the disk.
The Fix
Scan all AWS regions for unattached EBS volumes and remove them.
How to Apply the Fix
Run this AWS CLI command to list all unattached volumes in your default region:
aws ec2 describe-volumes \
--filters Name=status,Values=available \
--query "Volumes[*].{ID:VolumeId,Size:Size,Type:VolumeType,Created:CreateTime}" \
--output tableIf you find unattached volumes:
- Verify that the volume contains no required operational data.
- If necessary, create a backup snapshot:
- Delete the unattached volume:
A team with 500 GB of unattached gp2 volumes saves $50 every month immediately after running this cleanup.
3. Upgrade GP2 Volumes to GP3
The Problem
Many AWS accounts still use General Purpose SSD (gp2) storage for root volumes and database disks.
- GP2: Costs $0.10 per GB-month. IOPS performance couples directly to disk size (3 IOPS per GB). To obtain 3,000 IOPS, you must provision an expensive 1,000 GB disk.
- GP3: Costs $0.08 per GB-month. Provides a baseline performance of 3,000 IOPS and 125 MB/s throughput for free, regardless of disk volume size.
The Fix
Migrate all active volumes from gp2 to gp3. This modification reduces storage costs by 20% and improves disk throughput.
How to Apply the Fix
AWS Elastic Volumes allows online volume modification with zero downtime:
- Open the Amazon EC2 Console and select Volumes.
- Select an active volume with the volume type set to gp2.
- Click Actions, then click Modify volume.
- Change the volume type to General Purpose SSD (gp3).
- Keep default settings (3,000 IOPS / 125 MB/s throughput) and click Modify.
You can also run this command with the AWS CLI:
aws ec2 modify-volume \
--volume-id vol-0123456789abcdef0 \
--volume-type gp3The volume transitions through an optimizing state in the background. Performance does not degrade during migration.
4. Set CloudWatch Log Group Retention Periods
The Problem
By default, Amazon CloudWatch sets the retention period of new log groups to Never Expire.
Applications, load balancers, and container clusters generate millions of log lines daily. After twelve months, a standard production system can store several terabytes of uncompressed debug records.
AWS charges $0.03 per GB-month for CloudWatch log storage. Storing 3 terabytes of old logs costs $90 each month.
The Fix
Apply a standardized retention policy to all active log groups:
- Production environments: 30 days or 60 days.
- Staging and development environments: 7 days or 14 days.
How to Apply the Fix
Run this shell script to update all log groups currently set to infinite retention to 14 days:
aws logs describe-log-groups --query "logGroups[?!not_null(retentionInDays)].logGroupName" --output text | tr '\t' '\n' | while read -r group; do
echo "Updating retention for: $group"
aws logs put-retention-policy --log-group-name "$group" --retention-in-days 14
doneAWS automatically purges log events older than the configured threshold. Charges decrease on your next billing cycle.
5. Migrate Compute Workloads to AWS Graviton
The Problem
Legacy architectures use older x86 Intel (m5, c5, t3) processor types. These instance families provide lower price-to-performance metrics compared to modern ARM-based processors.
The Fix
Switch EC2 instances, Amazon ECS tasks, and Amazon RDS databases to AWS Graviton processors (t4g, m7g, c7g).
Graviton instances provide:
- Up to 20% lower hourly compute cost.
- Up to 40% higher price-performance for web applications, Python/Node runtimes, and databases.
How to Apply the Fix
For databases running on Amazon RDS (PostgreSQL or MySQL):
- Open the Amazon RDS Console.
- Select your database cluster, then click Modify.
- Under Instance configuration, switch the DB instance class from db.m5.large to db.m7g.large.
- Select Apply immediately during a scheduled maintenance window.
Database engines run natively on ARM architecture. No application adjustments are necessary.
For containerized microservices: Build multi-architecture container images using Docker buildx:
docker buildx build --platform linux/amd64,linux/arm64 -t my-app:latest --push .Summary of Results
Request an Architecture Review
Do you want an AWS Certified Solutions Architect to inspect your infrastructure?
3 Dices Technology performs comprehensive AWS Well-Architected and FinOps reviews for engineering teams. We identify security gaps, performance bottlenecks, and infrastructure cost leaks within 48 hours.
Book a Free 30-Minute Architecture Review or message our lead engineering team directly on WhatsApp.
About the author
3 Dices Team
3 Dices Technology is an AWS-certified engineering studio that builds high-performance cloud architecture, security systems, and DevOps automation.
Connect on LinkedIn