S3 Storage Classes, Versioning & Lifecycle
S3 offers multiple storage classes optimized for different access patterns. Choosing the right class is the biggest cost lever. Lifecycle rules automate transitions and expirations.
Storage Classes Comparison
Class | Min Duration | Retrieval | Use Case
------------------------------|--------------|-------------|---------------------------
S3 Standard | none | immediate | Frequently accessed data
S3 Intelligent-Tiering | none | immediate | Unknown/changing access
S3 Standard-IA | 30 days | immediate | Infrequent, still fast
S3 One Zone-IA | 30 days | immediate | Reproducible infrequent
S3 Glacier Instant Retrieval | 90 days | milliseconds| Archives, quarterly access
S3 Glacier Flexible Retrieval | 90 days | min–hours | Backups, flexible timing
S3 Glacier Deep Archive | 180 days | 12–48 hours | Compliance, rarely neededSetting Storage Class on Upload
# Upload directly to a specific class
aws s3 cp logs.tar.gz s3://my-bucket/archives/ \
--storage-class GLACIER_IR # Instant Retrieval
# Storage class flags:
# STANDARD | REDUCED_REDUNDANCY | STANDARD_IA | ONEZONE_IA
# INTELLIGENT_TIERING | GLACIER | DEEP_ARCHIVE | GLACIER_IRVersioning
Versioning keeps all versions of an object. Once enabled on a bucket it cannot be fully disabled, only suspended. Deleting a versioned object adds a delete marker; the actual data remains.
# Enable versioning
aws s3api put-bucket-versioning --bucket my-bucket \
--versioning-configuration Status=Enabled
# List all versions of an object
aws s3api list-object-versions --bucket my-bucket --prefix images/photo.jpg
# Download a specific version
aws s3api get-object --bucket my-bucket --key images/photo.jpg \
--version-id abc123XYZ output.jpg
# Permanently delete a specific version (not just add delete marker)
aws s3api delete-object --bucket my-bucket --key images/photo.jpg \
--version-id abc123XYZ
# Restore an accidentally deleted object by removing the delete marker
aws s3api delete-object --bucket my-bucket --key images/photo.jpg \
--version-id <delete-marker-version-id>Lifecycle Rules
Lifecycle rules automate transitions between storage classes and deletion of old objects. Apply them via the console or JSON policy.
{
"Rules": [
{
"ID": "archive-logs",
"Status": "Enabled",
"Filter": { "Prefix": "logs/" },
"Transitions": [
{ "Days": 30, "StorageClass": "STANDARD_IA" },
{ "Days": 90, "StorageClass": "GLACIER_IR" },
{ "Days": 365, "StorageClass": "DEEP_ARCHIVE" }
],
"Expiration": { "Days": 2555 }
},
{
"ID": "clean-incomplete-uploads",
"Status": "Enabled",
"Filter": {},
"AbortIncompleteMultipartUpload": { "DaysAfterInitiation": 7 }
},
{
"ID": "expire-old-versions",
"Status": "Enabled",
"Filter": {},
"NoncurrentVersionTransitions": [
{ "NoncurrentDays": 30, "StorageClass": "GLACIER_IR" }
],
"NoncurrentVersionExpiration": { "NoncurrentDays": 90 }
}
]
}# Apply lifecycle config
aws s3api put-bucket-lifecycle-configuration \
--bucket my-bucket \
--lifecycle-configuration file://lifecycle.json
# View current lifecycle config
aws s3api get-bucket-lifecycle-configuration --bucket my-bucketS3 Intelligent-Tiering
Intelligent-Tiering automatically moves objects between access tiers based on usage. No retrieval fees, no minimum duration penalties. Small per-object monitoring fee. Best for data with unknown or changing access patterns.
Frequent Access tier: actively used objects
Infrequent Access tier: objects not accessed for 30 days
Archive Instant Access: not accessed for 90 days (optional activation)
Archive Access: not accessed for 90–730 days (optional, need restore)
Deep Archive Access: not accessed for 180–730+ days (optional)
Keep your own version of these notes — editable, searchable, and organised by your stack.
Start free