← Back
Storage Cost Optimization Guide
Service Overview
What is AWS Storage?
- Comprehensive storage services including EBS (Elastic Block Store), S3 (Simple Storage Service), and EFS (Elastic File System)
- EBS provides persistent block storage for EC2 instances with multiple volume types
- S3 offers object storage with multiple storage classes for different access patterns
- EFS provides scalable file storage for multiple EC2 instances
Why Cost Optimization Matters
- Storage often represents 15-25% of total AWS costs across organizations
- Rapid data growth can lead to exponential cost increases without proper management
- Multiple storage tiers and options create optimization opportunities but also complexity
- Common cost surprises include unused volumes, inappropriate storage classes, and over-provisioned IOPS
---
Cost Analysis & Monitoring
Key Cost Metrics to Track
Primary Cost Drivers:
- **EBS Volume Capacity** - $0.08-$0.125/GB-month depending on type (gp3 vs io2)
- **Provisioned IOPS** - $0.005-$0.065/IOPS-month with tiered pricing for high-performance volumes
- **S3 Storage Classes** - $0.023/GB (Standard) to $0.00099/GB (Deep Archive) with retrieval costs
- **Data Transfer** - Cross-region and internet egress charges
- **API Requests** - PUT, GET, LIST operations with varying costs per storage class
Cost Allocation Tags:
- Environment (prod, dev, test) for lifecycle management
- Application/Project for cost attribution
- DataClassification (hot, warm, cold, archive) for storage class optimization
- Owner/Team for accountability and cleanup responsibilities
Using the Power's Tools
Get Storage costs by service:
usePower("aws-cost-optimization", "awslabs.billing-cost-management-mcp-server", "cost_explorer", {
"operation": "getCostAndUsage",
"start_date": "2024-11-01",
"end_date": "2024-12-01",
"granularity": "MONTHLY",
"group_by": "[{\"Type\": \"DIMENSION\", \"Key\": \"SERVICE\"}]",
"metrics": "[\"UnblendedCost\"]",
"filters": "{\"Dimensions\": {\"Key\": \"SERVICE\", \"Values\": [\"Amazon Elastic Block Store\", \"Amazon Simple Storage Service\", \"Amazon Elastic File System\"]}}"
})
Analyze EBS usage patterns:
usePower("aws-cost-optimization", "awslabs.billing-cost-management-mcp-server", "cost_explorer", {
"operation": "getCostAndUsage",
"start_date": "2024-11-01",
"end_date": "2024-12-01",
"granularity": "DAILY",
"group_by": "[{\"Type\": \"DIMENSION\", \"Key\": \"USAGE_TYPE\"}]",
"metrics": "[\"UsageQuantity\", \"UnblendedCost\"]",
"filters": "{\"Dimensions\": {\"Key\": \"SERVICE\", \"Values\": [\"Amazon Elastic Block Store\"]}}"
})
Get EBS pricing information:
usePower("aws-cost-optimization", "awslabs.aws-pricing-mcp-server", "get_pricing", {
"service_code": "AmazonEC2",
"region": ["us-east-1", "us-west-2"],
"filters": [
{"Field": "productFamily", "Value": "Storage", "Type": "EQUALS"},
{"Field": "volumeType", "Value": "gp3", "Type": "EQUALS"}
]
})
Monitor EBS utilization for cost correlation:
usePower("aws-cost-optimization", "awslabs.cloudwatch-mcp-server", "get_metric_statistics", {
"namespace": "AWS/EBS",
"metric_name": "VolumeReadOps",
"dimensions": [{"Name": "VolumeId", "Value": "vol-1234567890abcdef0"}],
"start_time": "2024-11-01T00:00:00Z",
"end_time": "2024-12-01T00:00:00Z",
"period": 3600,
"statistics": ["Average", "Maximum"]
})
Create storage efficiency metrics:
usePower("aws-cost-optimization", "awslabs.cloudwatch-mcp-server", "get_metric_data", {
"metric_data_queries": [
{
"id": "iops_utilization",
"metric_stat": {
"metric": {
"namespace": "AWS/EBS",
"metric_name": "VolumeReadOps",
"dimensions": [{"Name": "VolumeId", "Value": "vol-1234567890abcdef0"}]
},
"period": 3600,
"stat": "Average"
}
},
{
"id": "cost_per_iop",
"expression": "iops_utilization / provisioned_iops"
}
],
"start_time": "2024-11-01T00:00:00Z",
"end_time": "2024-12-01T00:00:00Z"
})
---
Optimization Strategies
1. EBS Volume Optimization
Strategy Overview:
- Migrate from older generation volumes (gp2, io1) to newer, more cost-effective types (gp3, io2)
- Right-size volumes based on actual usage patterns
- Optimize IOPS and throughput provisioning independently
Implementation Steps:
1. Analyze current EBS utilization:
usePower("aws-cost-optimization", "awslabs.billing-cost-management-mcp-server", "compute_optimizer", {
"operation": "get_ebs_volume_recommendations"
})
2. gp2 to gp3 Migration Benefits:
- **20% cost reduction** on storage capacity ($0.10 → $0.08 per GB-month)
- **Independent IOPS/throughput scaling** - provision only what you need
- **Baseline performance:** 3,000 IOPS and 125 MB/s included free
- **Example savings:** 500GB gp2 ($50/month) → gp3 ($45/month) = 10% savings
3. io1 to io2 Migration Benefits:
- **Tiered IOPS pricing:** 30% savings on IOPS above 32,000
- **100x higher durability** (99.999% vs 99.8-99.9%)
- **Same performance** with better cost structure
- **Example:** 64,000 IOPS volume saves 14% ($4,410 → $3,786/month)
4. Volume Consolidation Strategy:
- Replace multiple gp2 volumes used for striping with single gp3 volume
- **Example:** 2x 500GB gp2 volumes ($100/month) → 1x 1TB gp3 ($85/month) = 15% savings
- Simplifies management while reducing costs
2. S3 Storage Class Optimization
When to Use Each Storage Class:
- **S3 Standard ($0.023/GB):** Frequently accessed data, millisecond access
- **S3 Standard-IA ($0.0125/GB):** Infrequently accessed, 30-day minimum, retrieval fees
- **S3 One Zone-IA ($0.01/GB):** Lower durability acceptable, single AZ storage
- **S3 Glacier Instant Retrieval ($0.004/GB):** Archive with millisecond access, 90-day minimum
- **S3 Glacier Flexible Retrieval ($0.0036/GB):** Archive with minutes-hours retrieval
- **S3 Glacier Deep Archive ($0.00099/GB):** Long-term archive, 180-day minimum
S3 Intelligent-Tiering Benefits:
- **Automatic optimization** based on access patterns
- **Up to 72% storage cost savings** using Archive Access tiers
- **No retrieval charges** when objects move between tiers
- **Monitoring cost:** $0.0025 per 1,000 objects
Analysis Commands:
// Check current S3 storage class distribution
usePower("aws-cost-optimization", "awslabs.billing-cost-management-mcp-server", "cost_explorer", {
"operation": "getCostAndUsage",
"start_date": "2024-11-01",
"end_date": "2024-12-01",
"granularity": "MONTHLY",
"group_by": "[{\"Type\": \"DIMENSION\", \"Key\": \"USAGE_TYPE\"}]",
"metrics": "[\"UnblendedCost\"]",
"filters": "{\"Dimensions\": {\"Key\": \"SERVICE\", \"Values\": [\"Amazon Simple Storage Service\"]}}"
})
3. EFS Cost Optimization
EFS Storage Classes:
- **Standard:** Frequently accessed files
- **Infrequent Access (IA):** Files accessed less than once per month
- **Archive:** Files accessed a few times per year, up to 93% savings vs S3
Throughput Mode Optimization:
- **Bursting Mode:** Default, scales with file system size
- **Provisioned Mode:** Pay for specific throughput, monitor utilization
- **Elastic Mode:** Automatically scales, pay for actual usage
Implementation:
// Monitor EFS utilization patterns
usePower("aws-cost-optimization", "awslabs.cloudwatch-mcp-server", "get_metric_statistics", {
"namespace": "AWS/EFS",
"metric_name": "MeteredIOBytes",
"dimensions": [{"Name": "FileSystemId", "Value": "fs-1234567890abcdef0"}],
"start_time": "2024-11-01T00:00:00Z",
"end_time": "2024-12-01T00:00:00Z",
"period": 3600,
"statistics": ["Sum"]
})
4. Lifecycle Management & Automation
EBS Snapshot Management:
- **Data Lifecycle Manager:** Automate snapshot creation and deletion
- **EBS Snapshot Archive:** 75% cost reduction for long-term retention
- **Cross-region replication:** Balance cost vs disaster recovery needs
S3 Lifecycle Policies:
- **Transition rules:** Automatically move objects to cheaper storage classes
- **Expiration rules:** Delete objects after specified periods
- **Incomplete multipart upload cleanup:** Remove failed uploads
Implementation Examples:
{
"Rules": [
{
"Status": "Enabled",
"Transitions": [
{
"Days": 30,
"StorageClass": "STANDARD_IA"
},
{
"Days": 90,
"StorageClass": "GLACIER"
},
{
"Days": 365,
"StorageClass": "DEEP_ARCHIVE"
}
]
}
]
}
5. Operational Monitoring & Alerting
Cost-Performance Correlation:
- Monitor IOPS utilization vs provisioned capacity
- Track storage growth rates and forecast costs
- Correlate access patterns with storage class efficiency
Implementation Examples:
// Monitor storage cost anomalies
usePower("aws-cost-optimization", "awslabs.cloudwatch-mcp-server", "describe_alarms", {
"alarm_name_prefix": "StorageCost",
"state_value": "ALARM"
})
// Analyze storage utilization patterns
usePower("aws-cost-optimization", "awslabs.cloudwatch-mcp-server", "get_metric_statistics", {
"namespace": "AWS/EBS",
"metric_name": "VolumeQueueLength",
"start_time": "2024-11-01T00:00:00Z",
"end_time": "2024-12-01T00:00:00Z",
"period": 3600,
"statistics": ["Average", "Maximum"]
})
---
Common Cost Pitfalls & Solutions
Pitfall 1: Unattached EBS Volumes
Problem Description:
- Volumes remain after EC2 instance termination
- Continues billing at full rate despite no usage
- Can accumulate to significant costs over time
Detection:
// Identify cost anomalies that might indicate unused resources
usePower("aws-cost-optimization", "awslabs.billing-cost-management-mcp-server", "cost_anomaly", {
"start_date": "2024-11-01",
"end_date": "2024-12-01",
"filters": "{\"Dimensions\": {\"Key\": \"SERVICE\", \"Values\": [\"Amazon Elastic Block Store\"]}}"
})
Solution:
- Implement automated cleanup using AWS Config rules
- Set up CloudWatch alarms for unattached volumes
- Use Trusted Advisor recommendations for identification
- Establish volume tagging and lifecycle policies
Pitfall 2: Over-Provisioned IOPS
Problem Description:
- Provisioning maximum IOPS without analyzing actual requirements
- io1/io2 volumes with consistently low utilization
- Paying for performance that's never used
Detection & Solution:
- Monitor VolumeReadOps and VolumeWriteOps metrics
- Compare actual IOPS usage to provisioned capacity
- Consider gp3 for workloads under 16,000 IOPS
- Use Compute Optimizer recommendations for right-sizing
Pitfall 3: Inappropriate S3 Storage Classes
Problem Description:
- Storing infrequently accessed data in S3 Standard
- Not leveraging Intelligent-Tiering for unknown access patterns
- Paying retrieval fees for frequently accessed IA data
Detection & Solution:
- Use S3 Storage Lens for access pattern analysis
- Implement S3 Storage Class Analysis
- Set up lifecycle policies based on access patterns
- Monitor retrieval costs vs storage savings
---
Real-World Scenarios
Scenario 1: Database Storage Optimization
Situation:
- Mid-size company with 50TB database storage across multiple RDS instances
- Using gp2 volumes with high IOPS requirements
- Monthly storage costs of $6,000+ with performance issues
Analysis Approach:
// Step 1: Analyze current EBS costs
usePower("aws-cost-optimization", "awslabs.billing-cost-management-mcp-server", "cost_explorer", {
"operation": "getCostAndUsage",
"start_date": "2024-11-01",
"end_date": "2024-12-01",
"granularity": "MONTHLY",
"group_by": "[{\"Type\": \"DIMENSION\", \"Key\": \"USAGE_TYPE\"}]",
"metrics": "[\"UnblendedCost\"]",
"filters": "{\"Dimensions\": {\"Key\": \"SERVICE\", \"Values\": [\"Amazon Elastic Block Store\"]}}"
})
// Step 2: Get EBS optimization recommendations
usePower("aws-cost-optimization", "awslabs.billing-cost-management-mcp-server", "compute_optimizer", {
"operation": "get_ebs_volume_recommendations"
})
// Step 3: Compare gp3 pricing
usePower("aws-cost-optimization", "awslabs.aws-pricing-mcp-server", "get_pricing", {
"service_code": "AmazonEC2",
"region": ["us-east-1"],
"filters": [
{"Field": "volumeType", "Value": "gp3", "Type": "EQUALS"}
]
})
Solution Implementation:
- Migrated from gp2 to gp3 volumes using Elastic Volumes
- Right-sized IOPS based on actual usage patterns (reduced from 16,000 to 8,000 IOPS average)
- Consolidated multiple volumes where possible
Results:
- **35% cost reduction** ($6,000 → $3,900/month)
- **Improved performance** with consistent IOPS delivery
- **Simplified management** with fewer volumes to monitor
Scenario 2: Data Lake Storage Optimization
Situation:
- Large enterprise with 500TB+ data lake in S3
- All data stored in S3 Standard class
- Rapid growth causing budget concerns
Analysis Approach:
// Analyze S3 access patterns
usePower("aws-cost-optimization", "awslabs.billing-cost-management-mcp-server", "cost_explorer", {
"operation": "getCostAndUsage",
"start_date": "2024-11-01",
"end_date": "2024-12-01",
"granularity": "MONTHLY",
"group_by": "[{\"Type\": \"DIMENSION\", \"Key\": \"USAGE_TYPE\"}]",
"metrics": "[\"UnblendedCost\"]",
"filters": "{\"Dimensions\": {\"Key\": \"SERVICE\", \"Values\": [\"Amazon Simple Storage Service\"]}}"
})
Solution Implementation:
- Implemented S3 Intelligent-Tiering for unknown access patterns
- Created lifecycle policies for predictable data (logs, backups)
- Moved historical data (>1 year) to Glacier Deep Archive
Results:
- **60% storage cost reduction** on archived data
- **Automated optimization** reducing manual management
- **Maintained access performance** for active datasets
---
Integration with Other Services
Cost Impact of Service Integrations
Common Integration Patterns:
- **EBS with EC2:** Volume types should match instance performance characteristics
- **S3 with CloudFront:** Reduce data transfer costs through caching
- **EFS with multiple EC2:** Shared storage reduces individual EBS volume needs
Cross-Service Optimization:
- **Regional co-location:** Minimize data transfer charges between services
- **Reserved capacity coordination:** Align EBS and EC2 Reserved Instance strategies
- **Backup consolidation:** Use AWS Backup for unified lifecycle management
Analysis Commands:
// Analyze cross-service storage costs
usePower("aws-cost-optimization", "awslabs.billing-cost-management-mcp-server", "cost_explorer", {
"operation": "getCostAndUsage",
"start_date": "2024-11-01",
"end_date": "2024-12-01",
"granularity": "MONTHLY",
"group_by": "[{\"Type\": \"DIMENSION\", \"Key\": \"SERVICE\"}]",
"metrics": "[\"UnblendedCost\"]",
"filters": "{\"Dimensions\": {\"Key\": \"SERVICE\", \"Values\": [\"Amazon Elastic Block Store\", \"Amazon Simple Storage Service\", \"Amazon Elastic File System\", \"Amazon CloudFront\"]}}"
})
---
Monitoring & Alerting
Key Metrics to Monitor
Cost Metrics:
- Daily storage spend trends by service and storage class
- Cost per GB metrics across different storage types
- Growth rate and forecasting for capacity planning
Usage Metrics:
- EBS IOPS utilization vs provisioned capacity
- S3 access patterns and retrieval frequencies
- EFS throughput utilization vs provisioned/bursting limits
Operational Metrics (via CloudWatch):
- Volume queue length and latency metrics
- S3 request rates and error rates
- EFS client connections and throughput
Recommended Alerts
Budget Alerts:
// Monitor storage-specific budget performance
usePower("aws-cost-optimization", "awslabs.billing-cost-management-mcp-server", "budgets", {
"filters": "{\"Dimensions\": {\"Key\": \"SERVICE\", \"Values\": [\"Amazon Elastic Block Store\", \"Amazon Simple Storage Service\", \"Amazon Elastic File System\"]}}"
})
Anomaly Detection:
// Set up anomaly monitoring for storage services
usePower("aws-cost-optimization", "awslabs.billing-cost-management-mcp-server", "cost_anomaly", {
"start_date": "2024-11-01",
"end_date": "2024-12-01",
"filters": "{\"Dimensions\": {\"Key\": \"SERVICE\", \"Values\": [\"Amazon Elastic Block Store\", \"Amazon Simple Storage Service\"]}}"
})
Operational Alerts:
// Monitor storage-related operational alarms
usePower("aws-cost-optimization", "awslabs.cloudwatch-mcp-server", "describe_alarms", {
"alarm_name_prefix": "Storage",
"state_value": "ALARM"
})
---
Best Practices Summary
✅ Do:
- **Use gp3 as default** - 20% cheaper than gp2 with better performance control
- **Implement S3 lifecycle policies** - Automatically transition data to appropriate storage classes
- **Monitor IOPS utilization** - Right-size provisioned IOPS based on actual usage
- **Tag all storage resources** - Enable cost allocation and automated cleanup
- **Use S3 Intelligent-Tiering** - For data with unknown or changing access patterns
❌ Don't:
- **Leave volumes unattached** - Implement automated cleanup for unused resources
- **Over-provision IOPS** - Start with baseline and scale based on monitoring
- **Store everything in S3 Standard** - Analyze access patterns and use appropriate classes
- **Ignore snapshot lifecycle** - Implement retention policies to control backup costs
- **Mix storage types randomly** - Align storage characteristics with workload requirements
🔄 Regular Review Cycle:
- **Weekly:** Monitor unattached volumes and unusual cost spikes
- **Monthly:** Review storage growth trends and lifecycle policy effectiveness
- **Quarterly:** Analyze storage class distribution and optimization opportunities
- **Annually:** Review Reserved Instance strategies and long-term archival policies
---
Additional Resources
AWS Documentation
- [EBS Volume Types and Performance](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebs-volume-types.html)
- [S3 Storage Classes](https://aws.amazon.com/s3/storage-classes/)
- [EFS Performance Modes](https://docs.aws.amazon.com/efs/latest/ug/performance.html)
Tools & Calculators
- [AWS Pricing Calculator](https://calculator.aws/) for storage cost modeling
- [S3 Storage Lens](https://aws.amazon.com/s3/storage-analytics-insights/) for usage analytics
- [AWS Compute Optimizer](https://aws.amazon.com/compute-optimizer/) for EBS recommendations
Related Power Guidance
- EC2 AMD Cost Optimization for compute-storage alignment
- Lambda Cost Optimization for serverless storage patterns
- Database optimization guides for storage-intensive workloads
---
Service Codes: AmazonEC2 (EBS), AmazonS3, AmazonEFS
Last Updated: January 2026
Review Cycle: Quarterly