S3 Lifecycle Policies: The Cheapest Storage Cost Win You’re Ignoring
The storage bill nobody reads
S3 is where the cloud’s cheapest storage story starts. But “cheap” can become surprisingly expensive when the data just sits there forever.
Most teams set up an S3 bucket for a clear purpose: logs, backups, uploads, archives. Over time the bucket fills up. Object counts grow. Storage classes stay in the default Standard tier. Old versions pile up. Incomplete multipart uploads linger. And the monthly cost slowly becomes one of those background expenses nobody questions.
A few lifecycle rules can fix most of this automatically. The problem is that many buckets were created by someone who has since left the company, and the rules were either never added or were added for one use case and never generalized.
What an S3 lifecycle policy actually does
A lifecycle rule is an S3-level instruction that moves or deletes objects based on age and prefix or tag conditions.
Common actions:
- Transition objects to a cheaper storage class after a number of days
- Standard → Standard-IA after 30 days
- Standard-IA → Glacier Instant Retrieval after 90 days
- Glacier Instant Retrieval → Glacier Flexible Retrieval or Deep Archive after 1–2 years
- Expire old versions of objects
- Delete incomplete multipart uploads after a few days
- Delete entire objects after a defined retention period
The cost differences are meaningful. For infrequently accessed data, Standard-IA is roughly half the storage price of Standard. Glacier Flexible Retrieval is a small fraction. Deep Archive is the cheapest long-term option. The key is matching the transition to how the data is actually used.
The three biggest S3 money leaks
1. Data in Standard storage that is rarely accessed
A log bucket, an old dataset, or a media archive sitting in S3 Standard is usually over-provisioned. If an object has not been accessed in 30 or 90 days, it is a candidate for Standard-IA or Glacier.
2. Versioning without an expiration rule
S3 versioning is a good safety feature. Without an expiration rule, every update creates a permanent old copy. Buckets that hold changing data can accumulate hundreds of versions per object. The current version might be small; the version stack can be many times larger.
3. Incomplete multipart uploads
When a multipart upload fails or is abandoned, the uploaded parts stay in S3. They are not visible in the default console view, but they are billed. A rule that deletes incomplete multipart uploads after 7 days almost always saves money and causes no harm.
How to audit your own buckets
List buckets and check which have lifecycle rules:
aws s3api list-buckets --query 'Buckets[*].Name' --output table
aws s3api get-bucket-lifecycle-configuration --bucket <your-bucket>
If the second command returns an error, the bucket has no lifecycle rules. That is not always bad, but it is a signal to investigate.
Check storage class distribution:
aws s3api list-objects-v2 \
--bucket <your-bucket> \
--query 'Contents[*].{Key:Key,Size:Size,StorageClass:StorageClass}' \
--output table
For a larger bucket, use S3 Storage Lens or run a report via CloudWatch. You are looking for:
- High object counts with no lifecycle rules
- A large share of data in Standard storage
- Buckets older than a few months with heavy version counts
- Buckets with no incomplete-multipart cleanup
Example lifecycle rules that cover most cases
A sensible default for a log or backup bucket:
aws s3api put-bucket-lifecycle-configuration \
--bucket <your-bucket> \
--lifecycle-configuration file://lifecycle.json
lifecycle.json:
{
"Rules": [
{
"ID": "cleanup-incomplete-multipart",
"Status": "Enabled",
"Filter": {},
"AbortIncompleteMultipartUpload": {
"DaysAfterInitiation": 7
}
},
{
"ID": "transition-old-objects",
"Status": "Enabled",
"Filter": {},
"Transitions": [
{ "Days": 30, "StorageClass": "STANDARD_IA" },
{ "Days": 90, "StorageClass": "GLACIER_IR" }
]
},
{
"ID": "expire-noncurrent-versions",
"Status": "Enabled",
"Filter": {},
"NoncurrentVersionExpiration": {
"NoncurrentDays": 30
}
}
]
}
This is a starting point, not a universal rule. A bucket that serves user uploads daily should not be treated like an annual compliance archive. Adjust transitions to match actual access patterns.
How GreenOps Scan can help
The s3 module in the free GreenOps Scan CLI flags:
- buckets with no lifecycle configuration
- buckets with versioning enabled but no noncurrent-version expiration
- large buckets that are still primarily in Standard storage
- buckets with suspicious storage growth over time
Run it on a dev or sandbox account:
npx greenops-scan --profile dev --region us-east-1 --modules s3
Or use the Docker image:
docker run --rm -it \
-v ~/.aws:/home/greenops/.aws:ro \
-v "$(pwd)/reports:/reports" \
-e AWS_PROFILE=dev \
spidgorny/greenops-scan:latest \
--region us-east-1 --modules s3
Each finding includes the bucket name, the issue, and a confidence level. Review the recommendations before applying rules, especially in production accounts.
What to expect from cleanup
A single bucket with a few terabytes of logs or backups can move from a few hundred dollars per month in Standard storage to a fraction of that in Glacier. The exact saving depends on:
- how much data is infrequently accessed
- how aggressively you can move data to colder tiers
- how long versions and incomplete uploads have been accumulating
- your data-retention and compliance requirements
Savings are recurring. Once the lifecycle rules are in place, they continue to move and delete data automatically. That is the real win: set the rule once, and the bill improves every month.
Start with the obvious buckets
- List your buckets and identify the oldest, largest ones.
- Check whether they have lifecycle rules and versioning rules.
- Look at actual access patterns in S3 access logs or Storage Lens.
- Add a lifecycle rule for incomplete multipart uploads first — it is always safe.
- Add transition and version-expiration rules for infrequently accessed data.
- Review after 30 days to confirm the storage class mix is shifting.
S3 is one of the few AWS services where a small configuration change can cut costs for years. It is worth a 30-minute audit.
Tags: #AWS #CloudCostOptimization #FinOps #S3 #StorageCost #LifecyclePolicy #CloudWaste #GreenOps
