← Back to Blog

How I Reduced AWS Costs by 70% Without Sacrificing Performance

A practical guide to optimizing AWS infrastructure costs through smart architecture decisions, reserved instances, and serverless solutions.

Cover image for How I Reduced AWS Costs by 70% Without Sacrificing Performance
AWSCost OptimizationCloudDevOps

The situation

The monthly AWS bill was $5,000. After three months of focused optimization, it reached $1,500 while performance and reliability improved. The work centered on idle capacity, workload fit, and storage lifecycle rules.

Start with usage data. The largest savings usually come from resources that are provisioned continuously but used only occasionally.

Use serverless for low-traffic services

Twelve services averaging fewer than 100 requests per minute moved from always-on EC2 instances to Lambda and API Gateway. The migration required stateless handlers and cold-start testing, but reduced their monthly cost from $360 to about $12.

bash
# Before: 12 x t3.medium instances
# After: Lambda + API Gateway
# Result: $348/month saved

The important decision was not that serverless is always cheaper. It was that these services had bursty traffic, short execution times, and no requirement for a permanently warm process. A workload profile made the architecture choice defensible.

Measure the migration, not just the invoice

Before moving a service, record request latency, error rate, concurrency, memory usage, and downstream dependency behavior. After the change, compare the same measurements over a representative traffic window. A lower bill is not a win if it creates retries, timeouts, or an exhausted database connection pool.

Do not move a steady, latency-sensitive workload to Lambda because the pricing page looks attractive. Cold starts, concurrency limits, and downstream connection behavior must fit the workload.

Match capacity to failure tolerance

Batch jobs, CI runners, and development environments moved to Spot capacity. These workloads already tolerate interruption, so mixed instance types and retryable jobs delivered substantial savings without adding production risk.

We made interruption a normal event: jobs checkpointed progress, runners recreated themselves, and queues retried work safely. The architecture carried the failure instead of asking an operator to rescue a machine at 2 a.m.

Control the blast radius

Spot capacity stayed away from stateful databases and customer-facing singleton services. Capacity providers used multiple instance families and availability zones, while autoscaling policies kept a small on-demand baseline for critical work.

text
Safe candidates:
- CI runners
- Batch processors
- Development environments
- Stateless workers

Poor candidates:
- Primary databases
- Singleton control-plane services
- Workloads without retry or checkpoint logic

Give storage a lifecycle

Data that had not been accessed for 30 to 90 days moved through S3 Standard-IA and Glacier using lifecycle rules. Intelligent-Tiering remained the better choice for data with unpredictable access patterns.

The lifecycle policy was paired with ownership tags, retention requirements, and a restore test. Archiving data without knowing who owns it or how quickly it must be recovered is not optimization; it is delayed incident response.

Make savings part of delivery

Dashboards tracked spend by account, service, environment, and owner. Budgets alerted teams before a surprise became a monthly trend. Infrastructure changes also included cost impact in the review description, alongside security and reliability impact.

Put guardrails around every saving

Compare more than the invoice. Track cost per request, job, customer, or environment alongside p95 latency, error rate, and saturation. Change one major cost driver at a time, give the change an owner, and agree on a rollback threshold before rollout. If spend falls while retries or support tickets rise, the bill has merely moved to a less convenient department.

Cost work is a feedback loop: measure a workload, change one lever, verify service health, then keep or roll back the change.
Cost work is a feedback loop: measure a workload, change one lever, verify service health, then keep or roll back the change.

A lower number on the invoice is not a customer outcome. The useful question is what capability we kept for each dollar we stopped spending.

The cost review after the graph turns green
  • Tag every billable resource with owner and environment
  • Review idle capacity before buying more capacity
  • Test restore paths before moving data to archival tiers
  • Set budgets and alerts at account and service boundaries
  • Recheck savings after traffic and architecture change

Review cost changes monthly. Savings are durable only when ownership, budgets, and lifecycle policies are part of normal operations.

← Back to BlogHome