Cloud costs can spiral out of control without proper governance. This guide covers proven strategies to optimize cloud spending.
Cost Optimization Pillars
- 1Right-Sizing: Match resources to workload needs
- 2Reserved Instances: Commit for better rates
- 3Spot Instances: Use spare capacity
- 4Auto-Scaling: Scale based on demand
- 5Storage Optimization: Use appropriate storage tiers
AWS Cost Optimization
Right-Sizing EC2
typescript
// Analyze CloudWatch metrics to find right size
async function recommendInstanceType(instanceId: string) {
const cloudwatch = new AWS.CloudWatch();
const cpu = await cloudwatch.getMetricStatistics({
Namespace: 'AWS/EC2',
MetricName: 'CPUUtilization',
Dimensions: [{ Name: 'InstanceId', Value: instanceId }],
StartTime: new Date(Date.now() - 30 * 24 * 60 * 60 * 1000),
EndTime: new Date(),
Period: 86400,
Statistics: ['Average']
}).promise();
const avgCpu = cpu.Datapoints.reduce((sum, d) => sum + d.Average, 0) / cpu.Datapoints.length;
if (avgCpu < 20) return 't3.medium'; // Downsize
if (avgCpu > 80) return 'm5.large'; // Upsize
return 't3.small'; // Current size OK
}Reserved Instances
typescript
// Calculate RI savings
async function calculateRISavings(instanceType: string, hoursPerMonth: number) {
const onDemandRate = await getOnDemandRate(instanceType);
const riRate = await getReservedInstanceRate(instanceType);
const onDemandCost = onDemandRate * hoursPerMonth;
const riCost = riRate * hoursPerMonth;
const savings = onDemandCost - riCost;
return {
onDemandCost,
riCost,
savings,
savingsPercentage: (savings / onDemandCost) * 100
};
}Spot Instances
typescript
// Launch spot instances with fallback
async function launchWithSpot(instanceType: string, count: number) {
const ec2 = new AWS.EC2();
try {
const spot = await ec2.requestSpotFleet({
SpotFleetRequestConfig: {
IamFleetRole: 'arn:aws:iam::123456789012:role/fleet',
SpotPrice: '0.05',
TargetCapacity: count,
LaunchSpecifications: [{
ImageId: 'ami-12345',
InstanceType: instanceType,
EbsOptimized: false
}]
}
}).promise();
return spot.SpotFleetRequestId;
} catch (error) {
// Fallback to on-demand
console.warn('Spot unavailable, using on-demand');
return launchOnDemand(instanceType, count);
}
}Kubernetes Cost Optimization
Resource Requests and Limits
yaml
# Properly sized resources
apiVersion: apps/v1
kind: Deployment
metadata:
name: webapp
spec:
replicas: 3
template:
spec:
containers:
- name: app
image: myapp:latest
resources:
requests:
cpu: "250m"
memory: "256Mi"
limits:
cpu: "500m"
memory: "512Mi"Horizontal Pod Autoscaling
yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: webapp-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: webapp
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70Monitoring and Alerts
typescript
// Set up budget alerts
async function createBudgetAlert(amount: number, email: string) {
const billing = new AWS.Budgets();
await billing.putBudget({
AccountId: '123456789012',
Budget: {
BudgetLimit: { Amount: amount.toString(), Unit: 'USD' },
TimeUnit: 'MONTHLY',
BudgetType: 'COST'
}
}).promise();
await billing.notifyBudget({
AccountId: '123456789012',
BudgetName: 'monthly-budget',
Notification: {
NotificationType: 'ACTUAL',
ComparisonOperator: 'GREATER_THAN',
Threshold: 80
},
Subscribers: [{
SubscriptionType: 'EMAIL',
Address: email
}]
}).promise();
}Best Practices
- 1Monitor costs continuously
- 2Set up budget alerts
- 3Review resources regularly
- 4Use auto-scaling
- 5Leverage serverless when appropriate
- 6Clean up unused resources
- 7Use cost calculators for estimates
Conclusion
Cloud cost optimization is an ongoing process. Implement monitoring, right-size resources, and use purchasing options strategically to maximize cloud ROI.