Traditional EC2 architecture running 24/7
Serverless architecture with usage-based pricing
The Challenge: A dental practice management platform was spending nearly $500/month on AWS despite serving only 50,000 daily active users. After analyzing their usage patterns, we discovered the infrastructure was vastly over-provisioned for the actual workload.
🔍 The Initial Setup (What Was Wrong)
When we audited their AWS account, here's what we found:
- 3x t3.medium EC2 instances ($90/month) - Running 24/7 at 8% average utilization
- Application Load Balancer ($22.50/month) - Processing minimal traffic
- RDS PostgreSQL db.t3.small ($245/month) - Drastically oversized for 2GB database
- NAT Gateway ($45/month) - Handling 50GB/month traffic
- CloudWatch Logs ($18/month) - Storing everything without retention policies
- EBS volumes ($36/month) - 300GB provisioned, 80GB used
- Unused resources ($30/month) - Old snapshots, detached volumes, stopped instances
💡 Key Finding
The application had 95% of its traffic between 9 AM - 5 PM PST. EC2 instances sat completely idle 70% of the time, yet we were paying for 100% uptime. This is the perfect serverless use case.
📋 Our 5-Step Optimization Process
Step 1: Traffic Pattern Analysis
We analyzed 30 days of CloudWatch metrics to understand actual usage. Peak traffic: 5M requests/month during business hours. Off-peak: Nearly zero traffic.
Step 2: Architecture Redesign
Migrated from EC2 to serverless: Lambda for API, Aurora Serverless for database, S3 + CloudFront for static assets. Compare architectures in our serverless vs traditional guide.
Step 3: Database Optimization
Switched from always-on RDS to Aurora Serverless v2. Automatically scales from 0.5 to 2 ACUs based on demand. Cost: $43/month vs $245/month.
Step 4: Network Cost Reduction
Eliminated NAT Gateway by moving Lambda to public subnets with VPC endpoints. Saved $45/month instantly.
Step 5: Resource Cleanup & Monitoring
Deleted unused snapshots, set CloudWatch log retention to 7 days, right-sized everything. Set up cost alerts to prevent drift.
💰 Complete Cost Breakdown
Before (Traditional Architecture):
- EC2 instances (3x t3.medium): $90.00
- Application Load Balancer: $22.50
- RDS PostgreSQL (db.t3.small): $245.00
- NAT Gateway: $45.00
- EBS Volumes (300GB): $36.00
- CloudWatch Logs: $18.00
- Unused resources: $30.50
- Total: $487.00/month
After (Serverless Architecture):
- Lambda (5M requests, 512MB): $21.00
- API Gateway: $17.50
- Aurora Serverless v2 (0.5-2 ACU): $43.00
- S3 + CloudFront: $8.00
- CloudWatch (optimized): $3.50
- Total: $73.00/month
Monthly Savings: $414 (85% reduction)
Annual Savings: $4,968
🚀 The Migration Process
Week 1: Planning & Architecture
We created a detailed migration plan, designed the new serverless architecture, and set up the development environment. Used our serverless development services for the migration.
Week 2: Development & Testing
Converted the monolithic application to Lambda functions, implemented API Gateway, migrated database to Aurora Serverless. Comprehensive testing in staging environment.
Week 3: Gradual Rollout
Blue-green deployment with Route 53 weighted routing. Started at 10% traffic, monitored for issues, gradually increased to 100%. Zero downtime migration.
Week 4: Optimization & Monitoring
Fine-tuned Lambda memory allocation, implemented caching strategies, set up comprehensive monitoring and alerting. Used techniques from our Lambda cost optimization guide.
📊 Performance Impact
Beyond cost savings, the migration delivered significant performance improvements:
- Response Time: Decreased from 450ms to 180ms average
- Availability: Increased from 99.5% to 99.95%
- Scalability: Automatic scaling to handle traffic spikes (previously manual)
- Deployment Speed: From 45 minutes to 5 minutes
- Maintenance Time: Reduced from 8 hours/month to 1 hour/month
🎯 Key Lessons Learned
- Measure Before Optimizing: CloudWatch metrics revealed the actual usage patterns
- Right-Size Everything: Most resources were 3-5x larger than needed
- Serverless Isn't Always Cheaper: But for this sporadic workload pattern, it was perfect
- Hidden Costs Matter: NAT Gateway alone was $45/month doing nothing
- Set Up Alerts: Cost anomaly detection prevents future waste
🔧 Technical Implementation Highlights
# Lambda function optimizations applied:
- ARM64 architecture (20% cost savings)
- Right-sized memory (512MB optimal for this workload)
- Connection pooling for database
- Efficient cold start optimization
- Provisioned concurrency for peak hours only
# Database optimization:
- Aurora Serverless v2 (0.5 min, 2 max ACU)
- Auto-pause enabled after 5 minutes of inactivity
- Connection pooling through RDS Proxy
💡 Could This Work for Your Application?
This optimization strategy works best when:
- Traffic patterns are predictable and/or sporadic
- Current utilization is below 30%
- Application can be decomposed into stateless functions
- Database workload is variable
- You want to eliminate infrastructure management
Use our AWS Cost Calculator to estimate your potential savings. For detailed comparisons, see our EC2 vs Serverless cost analysis.
Want Similar Results for Your AWS Infrastructure?
We've helped 50+ companies reduce their AWS costs by an average of 60-85%. Get a free AWS assessment or check our pricing to get started.
Get Your Free Cost Analysis