· AWS  · 3 min read

AWS Cost Optimization — Real Strategies That Actually Work

AWS bills can spiral fast. Here are the strategies I use in production to cut cloud costs without sacrificing performance or reliability.

AWS bills can spiral fast. Here are the strategies I use in production to cut cloud costs without sacrificing performance or reliability.

Why AWS Bills Surprise Everyone

AWS is pay-as-you-go — which sounds great until you get your first serious bill. The problem isn’t that AWS is expensive, it’s that unused, over-provisioned, or forgotten resources silently accumulate cost. I’ve audited dozens of AWS accounts and the same patterns appear every time.

1. Right-Size Your EC2 and RDS Instances

The most common waste I find: instances sized for peak load that never actually arrive. Use AWS Cost Explorer’s rightsizing recommendations as a starting point, then validate with real metrics from CloudWatch or Grafana.

# Check average CPU utilization over 2 weeks
aws cloudwatch get-metric-statistics \
  --namespace AWS/EC2 \
  --metric-name CPUUtilization \
  --dimensions Name=InstanceId,Value=i-1234567890abcdef0 \
  --start-time 2024-01-01T00:00:00Z \
  --end-time 2024-01-14T00:00:00Z \
  --period 86400 \
  --statistics Average

If average CPU sits below 20%, you’re likely over-provisioned.

2. Use Spot Instances for Non-Critical Workloads

Spot instances offer up to 90% discount over On-Demand. For Kubernetes, I configure Karpenter to prefer Spot for worker nodes with automatic fallback:

apiVersion: karpenter.sh/v1alpha5
kind: Provisioner
metadata:
  name: default
spec:
  requirements:
    - key: karpenter.sh/capacity-type
      operator: In
      values: ["spot", "on-demand"]
    - key: node.kubernetes.io/instance-type
      operator: In
      values: ["m5.large", "m5.xlarge", "m4.large", "m4.xlarge"]
  ttlSecondsAfterEmpty: 30

Karpenter consolidates nodes automatically — another big cost win.

3. S3 Lifecycle Policies

Data that nobody accesses shouldn’t sit in S3 Standard. Move it automatically:

resource "aws_s3_bucket_lifecycle_configuration" "logs" {
  bucket = aws_s3_bucket.logs.id

  rule {
    id     = "transition-old-logs"
    status = "Enabled"

    transition {
      days          = 30
      storage_class = "STANDARD_IA"
    }

    transition {
      days          = 90
      storage_class = "GLACIER"
    }

    expiration {
      days = 365
    }
  }
}

This alone can cut S3 costs by 60–80% for log-heavy workloads.

4. CloudFront in Front of Everything

Serving assets directly from S3 or your origin costs more than it should. CloudFront caches at the edge, reducing origin requests dramatically. For a typical web app with static assets:

resource "aws_cloudfront_distribution" "app" {
  origin {
    domain_name = aws_s3_bucket.assets.bucket_regional_domain_name
    origin_id   = "S3-assets"

    s3_origin_config {
      origin_access_identity = aws_cloudfront_origin_access_identity.oai.cloudfront_access_identity_path
    }
  }

  default_cache_behavior {
    allowed_methods  = ["GET", "HEAD"]
    cached_methods   = ["GET", "HEAD"]
    target_origin_id = "S3-assets"

    viewer_protocol_policy = "redirect-to-https"

    min_ttl     = 0
    default_ttl = 86400
    max_ttl     = 31536000
  }

  enabled = true
}

5. Reserved Instances and Savings Plans

For predictable workloads (production databases, base Kubernetes nodes), commit to 1-year Reserved Instances or Compute Savings Plans. Savings of 30–40% over On-Demand with zero operational change.

6. Lambda — Don’t Overlook the Free Tier

AWS Lambda has a generous free tier (1M requests/month). Offloading lightweight, event-driven tasks from always-on EC2 instances to Lambda can eliminate those instances entirely.

Quick Wins Checklist

ActionTypical Saving
Delete unattached EBS volumes100% of that volume cost
Remove unused Elastic IPs$3.65/month each
Rightsize over-provisioned RDS30–50%
Enable S3 Intelligent-Tiering20–40% on S3
Spot instances for EKS nodesUp to 70% on compute
CloudFront caching30–60% on data transfer

Conclusion

AWS cost optimization isn’t a one-time task — it’s a habit. Set up monthly Cost Explorer reviews, tag everything (seriously, tag everything), and build cost awareness into your infrastructure-as-code from day one. The savings compound over time.


---
Back to Blog

Related Posts

View All Posts »
GitOps on Kubernetes with ArgoCD

GitOps on Kubernetes with ArgoCD

ArgoCD changed how I think about deployments. Here's how to set up GitOps for your Kubernetes workloads — and why you won't go back to manual kubectl applies.