AWS Cost Optimisation
EC2 Cost Optimisation: Strategies for Reducing Compute Spend
Practical strategies for optimising EC2 costs including right-sizing, Spot instances, Savings Plans, and automation techniques for Australian businesses.
CloudPoint Team
EC2 is often the largest line item on AWS bills. For Australian businesses running compute-intensive workloads, optimising EC2 costs can yield significant savings without sacrificing performance or reliability.
Understanding EC2 Pricing
EC2 costs come from:
- Instance hours: Charged per second (60-second minimum)
- Instance type: CPU, memory, storage, network performance
- Region: Sydney (ap-southeast-2) generally 10-15% more than US regions
- Operating system: Windows typically 30-40% more than Linux
- Tenancy: Dedicated instances cost significantly more
Example Pricing (Sydney region, Linux):
t3.medium:$0.0544/hour ($40/month)m6i.large:$0.125/hour ($91/month)c6i.xlarge:$0.221/hour ($161/month)
Running 24/7 adds up quickly.
Strategy 1: Right-Sizing
Assess Current Utilization
Use CloudWatch metrics to identify oversized instances:
aws cloudwatch get-metric-statistics \
--namespace AWS/EC2 \
--metric-name CPUUtilization \
--dimensions Name=InstanceId,Value=i-1234567890abcdef0 \
--start-time 2025-10-01T00:00:00Z \
--end-time 2025-11-01T00:00:00Z \
--period 3600 \
--statistics Average,Maximum \
--region ap-southeast-2
Red flags:
- Average CPU < 20%
- Maximum CPU < 40%
- Memory usage < 30%
- Network utilization minimal
AWS Compute Optimizer
Free service providing right-sizing recommendations:
aws compute-optimizer get-ec2-instance-recommendations \
--instance-arns arn:aws:ec2:ap-southeast-2:123456789012:instance/i-1234567890abcdef0
Provides:
- Current instance type and cost
- Recommended instance type
- Projected savings
- Performance risk assessment
Downsizing Process
- Identify candidates: Consistently underutilised instances
- Test in non-production: Verify performance with smaller size
- Monitor closely: Watch for performance degradation
- Implement in production: During maintenance window
- Validate: Confirm performance remains acceptable
Typical savings: 20-40% per right-sized instance
Strategy 2: Instance Scheduling
Stop instances when not needed.
Business Hours Schedule
For development and testing:
# lambda_function.py
import boto3
import os
from datetime import datetime
ec2 = boto3.client('ec2')
def lambda_handler(event, context):
# Sydney timezone (AEDT/AEST)
current_hour = datetime.now().hour
current_day = datetime.now().weekday() # 0 = Monday, 6 = Sunday
# Find instances with Schedule tag
instances = ec2.describe_instances(
Filters=[
{'Name': 'tag:Schedule', 'Values': ['business-hours']}
]
)
to_start = []
to_stop = []
for reservation in instances['Reservations']:
for instance in reservation['Instances']:
instance_id = instance['InstanceId']
state = instance['State']['Name']
# Business hours: Mon-Fri, 8 AM - 6 PM
is_business_hours = (
current_day < 5 and # Monday-Friday
8 <= current_hour < 18 # 8 AM - 6 PM
)
if is_business_hours and state == 'stopped':
to_start.append(instance_id)
elif not is_business_hours and state == 'running':
to_stop.append(instance_id)
if to_start:
ec2.start_instances(InstanceIds=to_start)
print(f"Started instances: {to_start}")
if to_stop:
ec2.stop_instances(InstanceIds=to_stop)
print(f"Stopped instances: {to_stop}")
return {
'statusCode': 200,
'started': len(to_start),
'stopped': len(to_stop)
}
Schedule Lambda with EventBridge (hourly):
{
"schedule": "cron(0 * * * ? *)"
}
Savings: 65-75% on scheduled instances (running 50 hours/week instead of 168)
AWS Instance Scheduler
Pre-built solution from AWS:
- Supports EC2 and RDS
- Flexible schedules
- Multiple time zones
- DynamoDB-based configuration
- CloudFormation deployment
Use case: Large environments with complex scheduling needs
Strategy 3: Spot Instances
Up to 90% discount compared to On-Demand.
When to Use Spot
Perfect for:
- Batch processing
- Data analysis
- CI/CD build servers
- Rendering farms
- Web scraping
- Stateless applications
- Fault-tolerant systems
Not suitable for:
- Databases
- Stateful applications (without proper handling)
- Applications requiring guaranteed availability
- Long-running processes that can’t checkpoint
Spot Best Practices
1. Diversify Instance Types
Don’t rely on single instance type:
{
"InstanceTypes": [
"m6i.large",
"m5.large",
"m5a.large",
"m5n.large"
],
"AllocationStrategy": "price-capacity-optimized"
}
2. Handle Interruptions Gracefully
Listen for 2-minute warning:
#!/bin/bash
# Check Spot instance termination notice
TERMINATION_NOTICE=$(curl -s http://169.254.169.254/latest/meta-data/spot/instance-action)
if [ -n "$TERMINATION_NOTICE" ]; then
echo "Spot instance terminating"
# Graceful shutdown
# - Save state
# - Drain connections
# - Deregister from load balancer
systemctl stop myapp
fi
3. Use Spot Fleet or Auto Scaling Groups
Maintain capacity despite interruptions:
# Auto Scaling Group with mixed instances
MixedInstancesPolicy:
InstancesDistribution:
OnDemandBaseCapacity: 2
OnDemandPercentageAboveBaseCapacity: 20
SpotAllocationStrategy: price-capacity-optimized
LaunchTemplate:
LaunchTemplateSpecification:
LaunchTemplateId: lt-1234567890abcdef0
Version: $Latest
Overrides:
- InstanceType: m6i.large
- InstanceType: m5.large
- InstanceType: m5a.large
80% Spot, 20% On-Demand for resilience.
Spot Placement Score
Evaluate likelihood of getting/maintaining Spot capacity:
aws ec2 get-spot-placement-scores \
--instance-types m6i.large m5.large m5a.large \
--target-capacity 10 \
--region ap-southeast-2
Choose instance types with highest scores.
Strategy 4: Savings Plans and Reserved Instances
Commit to usage, save 30-75%.
EC2 Instance Savings Plans
Most flexible Savings Plan:
Commitment: $X per hour for 1 or 3 years Discount: 30-55% (Sydney region) Flexibility:
- Change instance family
- Change instance size
- Change OS
- Change tenancy
- Works across regions (at lower discount)
Best for: Variable workloads, uncertain future needs
Compute Savings Plans
Broadest Savings Plan:
Commitment: $X per hour Discount: 35-60% Flexibility:
- EC2, Fargate, Lambda
- All instance families
- All regions
Best for: Mixed compute workloads
Reserved Instances
Specific instance type commitment:
Commitment: Specific instance type and region
Discount: 40-75%
Flexibility:
- Instance size flexibility within family
- AZ flexibility (regional RIs)
- Can sell on RI Marketplace
Best for: Predictable, steady-state workloads
Choosing the Right Option
Scenario 1: Production web servers (consistent load) → EC2 Instance Savings Plan (flexibility to change instance types)
Scenario 2: Mixed workload (EC2 + Lambda + Fargate) → Compute Savings Plan (covers all compute)
Scenario 3: Production database (RDS or self-managed) → Reserved Instance (highest discount, predictable usage)
Scenario 4: Variable workload → Partial Savings Plan (60-70% coverage) + On-Demand/Spot for spikes
Coverage Analysis
aws ce get-reservation-coverage \
--time-period Start=2025-10-01,End=2025-11-01 \
--granularity MONTHLY
Target coverage: 70-80% of baseline usage Leave uncovered: 20-30% for growth and flexibility
Strategy 5: Graviton Instances
AWS Graviton (ARM-based) processors offer better price-performance.
Graviton Benefits
- 20-40% better price-performance than x86
- Up to 60% lower cost for similar performance
- Better energy efficiency
Graviton Instance Families
- t4g: Burstable (most popular migration target)
- m7g: General purpose
- c7g: Compute optimised
- r7g: Memory optimised
Migration Considerations
Easy migrations:
- Java applications (JVM is platform-agnostic)
- Python, Ruby, Node.js, Go
- Containerized applications
- Amazon Linux 2, Ubuntu, Debian
Harder migrations:
- Windows applications (not supported)
- Legacy compiled binaries
- Software without ARM support
Example savings:
m6i.large: $0.125/hour
m7g.large: $0.0896/hour (28% cheaper, better performance)
Annual savings per instance: $250
For 100 instances: $25,000/year
Strategy 6: Auto Scaling
Scale capacity based on demand.
Target Tracking Scaling
Maintain specific metric:
{
"TargetValue": 60.0,
"PredefinedMetricSpecification": {
"PredefinedMetricType": "ASGAverageCPUUtilization"
},
"TargetTrackingScalingPolicyConfiguration": {
"TargetValue": 60.0,
"ScaleInCooldown": 300,
"ScaleOutCooldown": 60
}
}
Result: Maintain 60% CPU utilization, automatically add/remove instances
Scheduled Scaling
Predictable traffic patterns:
aws autoscaling put-scheduled-update-group-action \
--auto-scaling-group-name my-asg \
--scheduled-action-name scale-up-morning \
--recurrence "0 8 * * 1-5" \
--min-size 10 \
--max-size 20 \
--desired-capacity 15
aws autoscaling put-scheduled-update-group-action \
--auto-scaling-group-name my-asg \
--scheduled-action-name scale-down-evening \
--recurrence "0 18 * * 1-5" \
--min-size 2 \
--max-size 10 \
--desired-capacity 4
Savings: Run minimal capacity during off-peak hours
Predictive Scaling
Machine learning-based forecasting:
{
"MetricSpecifications": [{
"TargetValue": 60.0,
"PredefinedMetricPairSpecification": {
"PredefinedMetricType": "ASGCPUUtilization"
}
}],
"Mode": "ForecastOnly",
"SchedulingBufferTime": 600
}
AWS analyzes historical patterns and scales proactively.
Strategy 7: Instance Optimisation
Burstable Instances (T3/T4g)
For workloads with variable CPU usage:
How they work:
- Baseline CPU performance (e.g., 20% for t3.medium)
- Accumulate CPU credits during low usage
- Burst above baseline using credits
- Much cheaper than fixed-performance instances
Perfect for:
- Development environments
- Low-traffic web servers
- Batch processing
- Microservices with sporadic load
Cost comparison (Sydney):
t3.medium: $0.0544/hour (baseline 20%)
m6i.medium: $0.0625/hour (100% CPU always)
Monitoring: Watch CPUCreditBalance in CloudWatch
EBS-Optimized Instances
For I/O-intensive workloads, ensure EBS optimisation is enabled (most modern instances have it by default).
Enhanced Networking
Free performance improvement - ensure instances support:
- Elastic Network Adapter (ENA)
- Higher bandwidth
- Lower latency
- Lower jitter
Monitoring and Governance
Cost Allocation Tags
Tag all instances:
{
"Name": "web-server-prod-01",
"Environment": "production",
"Application": "customer-portal",
"Owner": "platform-team",
"CostCenter": "engineering",
"Schedule": "24x7"
}
CloudWatch Dashboards
Monitor costs in real-time:
- Instance count by type
- Total compute cost
- Savings Plan/RI coverage
- Spot usage percentage
Cost Anomaly Detection
Alert on unexpected spending:
aws ce create-anomaly-monitor \
--anomaly-monitor '{
"MonitorName": "EC2-Cost-Monitor",
"MonitorType": "DIMENSIONAL",
"MonitorDimension": "SERVICE",
"MonitorSpecification": {
"Dimensions": {
"Key": "SERVICE",
"Values": ["Amazon Elastic Compute Cloud - Compute"]
}
}
}'
EC2 Cost Optimisation Checklist
Immediate actions:
- Identify and stop unused instances
- Enable detailed monitoring for right-sizing analysis
- Implement instance scheduling for dev/test
- Review and delete old AMIs and snapshots
30-day actions:
- Right-size oversized instances
- Purchase Savings Plans for baseline usage
- Migrate workloads to Graviton where possible
- Implement Auto Scaling
90-day actions:
- Migrate appropriate workloads to Spot
- Optimize Auto Scaling policies
- Review and optimise EBS volumes
- Implement cost dashboards
Ongoing:
- Monthly cost reviews
- Quarterly Savings Plan coverage analysis
- Continuous right-sizing
- Regular optimisation reviews
Conclusion
EC2 cost optimisation combines multiple strategies - right-sizing, scheduling, Spot instances, Savings Plans, Graviton migration, and Auto Scaling. Start with quick wins like stopping unused instances and implementing schedules, then progress to more sophisticated strategies.
For Australian businesses, EC2 optimisation can reduce compute costs by 40-70% while maintaining or improving performance and reliability.
CloudPoint specialises in EC2 cost optimisation. We analyze your environment, model cost reduction scenarios, and implement sustainable optimisation strategies. Contact us for an EC2 cost assessment.
Want to Optimise Your EC2 Costs?
CloudPoint analyses your EC2 usage and implements right-sizing, Reserved Instances, and Savings Plans strategies. Get in touch to start saving.