devops

AWS Cost Optimization: 15 Proven Ways to Cut Your Cloud Bill

Practical AWS cost optimization strategies for engineers. Rightsize EC2, leverage Spot instances, optimize S3 storage, use Savings Plans, and implement FinOps.

July 2, 2026·5 min read·
#aws#cost-optimization#finops#cloud#ec2#s3

Introduction

AWS bills have a way of creeping up. That t2.micro becomes a c5.xlarge, the S3 bucket accumulates terabytes of forgotten data, and suddenly your monthly invoice is five figures.

The good news: most AWS cost optimization is low-hanging fruit. You don't need to re-architect your application. You need to apply the right tools and develop the right habits.

Here are 15 proven strategies, organized by service category, with concrete commands you can run today.

Compute: EC2, Lambda, and Containers

1. Rightsize Your EC2 Instances

AWS offers 700+ instance types. The one you picked three years ago is probably wrong for your current workload.

# Install AWS Compute Optimizer
aws compute-optimizer get-ec2-instance-recommendations \
  --query 'instanceRecommendations[*].[instanceArn,currentInstanceType,recommendationOptions[0].instanceType]' \
  --output table

Common findings:

  • 60% of instances are over-provisioned by 2x or more
  • Switching from Intel to AMD (e.g., m5.large to m5a.large) saves 10%
  • Switching to ARM (Graviton, e.g., m6g.large) saves 20-40%

2. Use Spot Instances for Fault-Tolerant Workloads

Spot instances cost 60-90% less than on-demand:

# Request Spot Instance
aws ec2 request-spot-instances \
  --spot-price "0.03" \
  --instance-count 1 \
  --launch-specification file://spec.json

Good candidates: CI/CD runners, batch processing, stateless web workers, dev/test environments. Use EC2 Auto Scaling groups with mixed instance policies to automatically fall back to on-demand when Spot is interrupted.

3. Graviton (ARM) Migration

ARM-based Graviton instances deliver 20-40% better price-performance:

# Multi-arch Docker build
FROM --platform=linux/arm64 node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --production
COPY . .
CMD ["node", "server.js"]

Build and push:

docker buildx build --platform linux/amd64,linux/arm64 -t myapp:latest --push .

4. Lambda: Right-Size Memory

Lambda charges per GB-second. Doubling memory doubles cost—but also doubles CPU. Run load tests at different memory settings:

aws lambda update-function-configuration \
  --function-name my-function \
  --memory-size 1024

Often, 1-2GB hits the sweet spot. Use AWS Lambda Power Tuning to find the optimal memory configuration automatically.

5. Scheduled Start/Stop for Non-Production

Dev and staging environments don't need to run 24/7:

# Lambda function to stop instances tagged Environment=staging at 8 PM
import boto3

def lambda_handler(event, context):
    ec2 = boto3.client('ec2')
    instances = ec2.describe_instances(
        Filters=[
            {'Name': 'tag:Environment', 'Values': ['staging', 'dev']},
            {'Name': 'instance-state-name', 'Values': ['running']}
        ]
    )
    ids = [i['InstanceId'] for r in instances['Reservations'] for i in r['Instances']]
    if ids:
        ec2.stop_instances(InstanceIds=ids)
        print(f"Stopped: {ids}")

Schedule this Lambda via EventBridge cron—saves ~65% on non-prod compute.

Storage: S3, EBS, and Backups

6. S3 Lifecycle Policies

Automatically transition objects to cheaper storage classes:

{
  "Rules": [{
    "Id": "MoveToGlacier",
    "Status": "Enabled",
    "Transitions": [
      {"Days": 30, "StorageClass": "STANDARD_IA"},
      {"Days": 90, "StorageClass": "GLACIER_INSTANT_RETRIEVAL"}
    ],
    "Expiration": {"Days": 365}
  }]
}
Storage ClassCost/GBRetrieval
S3 Standard$0.023Instant
S3 Intelligent-TieringAutoInstant
S3 Standard-IA$0.0125Instant
S3 Glacier Instant$0.004Milliseconds

7. Delete Unattached EBS Volumes

Every terminated EC2 instance can leave orphaned volumes:

aws ec2 describe-volumes \
  --filters Name=status,Values=available \
  --query 'Volumes[*].[VolumeId,Size,CreateTime]' \
  --output table

Take snapshots of anything important, then delete:

aws ec2 delete-volume --volume-id vol-0abc123def456

8. Clean Up Old Snapshots and AMIs

Snapshots accumulate silently:

aws ec2 describe-snapshots --owner-ids self \
  --query 'Snapshots[?StartTime<`2025-01-01`].[SnapshotId,StartTime,VolumeSize]' \
  --output table

Set up AWS Backup with retention policies instead of manual snapshots.

Networking and Data Transfer

9. Use VPC Endpoints

Data transfer between S3 and EC2 within the same region is free—but only through VPC endpoints:

aws ec2 create-vpc-endpoint \
  --vpc-id vpc-xxx \
  --service-name com.amazonaws.us-east-1.s3 \
  --route-table-ids rtb-xxx

Without endpoints, S3 traffic routes through NAT Gateways or Internet Gateways, incurring data transfer costs.

10. CloudFront for Content Delivery

Serve static assets through CloudFront—cheaper data transfer than S3 direct:

S3 direct: $0.09/GB (first 10TB)
CloudFront: $0.085/GB (US), $0.02/GB (reserved capacity)

Plus, CloudFront caches reduce origin requests to S3, cutting those costs too.

Financial Tools and Governance

11. AWS Savings Plans

Commit to 1 or 3 years of compute usage for up to 72% savings:

aws savingsplans describe-savings-plans

Compute Savings Plans apply to EC2, Lambda, and Fargate—far more flexible than Reserved Instances.

12. AWS Budgets and Alerts

Catch cost overruns before they surprise you:

aws budgets create-budget \
  --account-id 123456789012 \
  --budget file://budget.json \
  --notifications-with-subscribers file://notifications.json

Set alerts at 50%, 80%, and 100% of monthly budget. Route to Slack via SNS + Lambda.

13. Enable Cost Explorer and Tag Everything

Tags are the foundation of cost attribution:

Environment: production | staging | development
Team: backend | frontend | data
Service: api-server | worker | database
CostCenter: engineering-001

Without tags, you can't answer "who spent $5000 on EC2 last month?" Enable cost allocation tags in Billing Console and enforce tagging with SCPs or AWS Config rules.

14. Use Trusted Advisor

AWS Trusted Advisor (Business/Enterprise support) surfaces idle resources, underutilized instances, and unattached IPs:

aws support describe-trusted-advisor-check-result \
  --check-id <check-id> \
  --language en

15. Implement FinOps Culture

Tools help, but culture matters more:

  • Showback first: Make costs visible before charging teams
  • Weekly cost reviews: 15-minute standup looking at the AWS bill
  • Cost-per-feature: Calculate how much each API endpoint or feature costs
  • Gamify savings: Track "money saved this month" alongside velocity metrics

Conclusion

You don't need to implement all 15 strategies at once. Start with the top three: rightsize EC2 instances, enable S3 lifecycle policies, and set up AWS Budgets. Those three alone typically cut 30-40% of cloud waste.

The key insight: AWS cost optimization is not a one-time project. It's a continuous practice—like monitoring or security. Build it into your weekly routine, and your cloud bill will thank you.

#aws#cost-optimization#finops#cloud#ec2#s3
D
DevToCashAuthor

Senior DevOps/SRE Engineer · 10+ years · Professional Trader (IDX, Crypto, US Equities)

I write about real infrastructure patterns and trading strategies I use in production and in live markets. No courses, no affiliate hype — just documentation of what actually works.

More about me →