S3 Versioning & Lifecycle Rules

Learn to enable S3 versioning and lifecycle rules. This step-by-step AWS tutorial covers core concepts, hands-on configuration, and best practices for managing object versions and automated lifecycle transitions.

Focus: enable s3 versioning and lifecycle rules

Sponsored

Imagine your team accidentally overwrites a critical S3 object and there is no way to recover it. Or worse—you're paying monthly fees for thousands of old versions that you'll never read again. Without versioning, your data is one bad overwrite away from permanent loss; without lifecycle rules, you'll burn money on storage you don't need. This lesson gives you a simple, repeatable way to turn on S3 versioning and automate cleanup so your buckets are both resilient and cost-efficient.

Both features are managed per-bucket, so you can enable them independently. Versioning gives you a safety net for every object; lifecycle rules are your automated housekeeper that moves or deletes data based on age. Once these are in place, your S3 operations become much safer and cheaper.

The problem this lesson solves

S3 is the backbone of countless applications. Yet most teams treat it as a simple file cabinet—upload, download, forget. That approach creates several painful problems:

  • Accidental overwrites and deletes destroy data instantly with no recovery path.
  • Ransomware or malicious actors can erase your backups before you react.
  • Storage costs spiral from old versions and stale files that nobody cleans up.
  • Compliance and audit failures because you can't prove what data existed at a point in time.

Versioning solves the first three: it preserves every version of an object so you can always roll back. Lifecycle rules solve the cost problem: they move files to cheaper storage classes or delete them when you no longer need them.

If you've ever lost a file in production or stared at an S3 bill that made no sense, you know the pain. This lesson gives you the practical tools to avoid both.

Core concept / mental model

Think of S3 versioning as a time-traveling file system. When versioning is enabled, every PUT creates a new version instead of overwriting the old one. Deleting an object only adds a delete marker that hides the latest version—you can still access older versions. It's like having an undo button for every file operation.

Lifecycle rules are more like a shelf-life policy. They define actions based on an object's age (days since creation). You can transition objects to cheaper storage (like S3 Standard-IA or Glacier) or expire them entirely. The two features combine beautifully: versioning protects each version, and lifecycle rules clean up those versions automatically.

Pro tip: Versioning is a bucket-level setting—once enabled, you can't disable it, only suspend it. So enable it before you start uploading important data.

Here's a word diagram:

Bucket (versioning ON)
├── object_key: v1 (today)
├── object_key: v2 (tomorrow)
└── lifecycle rule → after 30 days transition to Glacier
                    after 90 days expire (delete)

How it works step by step

Enabling versioning is a one-click action in the console, but let's understand what happens under the hood.

Turning on versioning

  1. In the S3 console, select your bucket.
  2. Go to the Properties tab.
  3. Under Bucket Versioning, click Edit and choose Enable.
  4. Save changes. That's it—now every upload creates a version.

When you upload two files with the same key, the bucket retains both. The latest version is served by default, but you can list all versions and restore an older one.

How versions are tracked

Each object version gets a unique version ID (a long hex string). You can GET a specific version by passing its ID. Deleting an object adds a delete marker—the object appears gone, but versions remain. To permanently delete, you must delete all versions and the marker.

Creating lifecycle rules

  1. Go to the bucket's Management tab.
  2. Click Create lifecycle rule.
  3. Give the rule a name, and optionally restrict it to a prefix or tags.
  4. Add actions: Transition to a storage class or Expiration (delete).
  5. Set the number of days after creation.
  6. Enable the rule.

Rules apply to current versions and, if you choose, previous versions. That's crucial for cleanup of old versions.

Order of operations

Lifecycle rules evaluate objects daily (once per day). A rule acts only when an object is older than the specified days. Transitions happen over time, not instantly, so expect a delay—often up to 48 hours.

Pro tip: Use one lifecycle rule to transition current versions to cheaper storage, and a second rule to expire older versions. That keeps costs low without losing any version history.

Hands-on walkthrough

Let's put this into practice with the AWS CLI. You'll enable versioning on a test bucket and create lifecycle rules.

Prerequisites

  • AWS CLI installed and configured (aws configure)
  • An IAM user with permissions for S3 and lifecycle configuration

Step 1: Create a bucket and enable versioning

# Create a bucket (use a globally unique name)
aws s3api create-bucket --bucket my-versioned-bucket --region us-east-1

# Enable versioning
aws s3api put-bucket-versioning \
  --bucket my-versioned-bucket \
  --versioning-configuration Status=Enabled

Expected output: (no output—success is silent)

Verify it:

aws s3api get-bucket-versioning --bucket my-versioned-bucket

Output:

{
    "Status": "Enabled"
}

Step 2: Upload two versions of the same key

echo "version 1" > file.txt
aws s3 cp file.txt s3://my-versioned-bucket/file.txt

echo "version 2" > file.txt
aws s3 cp file.txt s3://my-versioned-bucket/file.txt

Now list all versions:

aws s3api list-object-versions \
  --bucket my-versioned-bucket \
  --prefix file.txt

Notice two versions with distinct VersionIds. The latest is served by default.

Step 3: Add a lifecycle rule

Create a JSON file lifecycle.json:

{
  "Rules": [
    {
      "ID": "Expire-old-versions",
      "Status": "Enabled",
      "Filter": { "Prefix": "" },
      "NoncurrentVersionExpiration": { "NoncurrentDays": 30 }
    }
  ]
}

Apply it:

aws s3api put-bucket-lifecycle-configuration \
  --bucket my-versioned-bucket \
  --lifecycle-configuration file://lifecycle.json

This rule expires previous versions after 30 days, keeping only the latest. Perfect for cost control.

Step 4: Verify the rule exists

aws s3api get-bucket-lifecycle-configuration --bucket my-versioned-bucket

Expected output shows your rule.

Compare options / when to choose what

You have several ways to manage object versions and lifecycle. Here's a comparison:

Approach Best for Pros Cons
Console Quick setups, learning Visual, no coding Hard to automate, error-prone at scale
AWS CLI Scripting, CI/CD Automatable, version-controlled Requires CLI knowledge
Terraform / CloudFormation Infrastructure as Code Reproducible, auditable Adds learning curve
S3 Object Lambda Real-time processing Fits serverless patterns Extra complexity

Variation: suspend versioning

If you no longer need new versions, you can suspend versioning. Existing versions remain, but new uploads overwrite the current version (no new version ID). This is ideal for buckets where you only need a recovery window for a limited time.

Variation: multi-factor authentication (MFA) delete

You can require MFA to delete versions permanently. Enable this via the CLI—it adds strong protection against malicious deletions.

aws s3api put-bucket-versioning \
  --bucket my-bucket \
  --versioning-configuration Status=Enabled,MFADelete=Enabled \
  --mfa "arn:aws:iam::123456789012:mfa/your-mfa 123456"

Variation: lifecycle transitions to Glacier

Instead of expiration, you can move older versions to Glacier for long-term archiving. This is cheaper than keeping them in Standard, yet still accessible if needed.

Troubleshooting & edge cases

Mistake: You deleted the latest version and can't see it

That's a delete marker. To restore, list versions and delete the marker.

aws s3api list-object-versions --bucket my-bucket --prefix myfile.txt
# Note the delete-marker VersionId
aws s3api delete-object --bucket my-bucket --key myfile.txt --version-id <marker-id>

Mistake: Lifecycle rule didn't transition as expected

Rules run once a day, and transitions can take up to 48 hours. If it's been longer, check the rule's filter—if it's restricted to a prefix, objects outside that prefix won't be affected.

Edge case: Versioning suspension doesn't delete old versions

Suspending only stops new versions. Old versions still exist and may incur costs. Add a lifecycle rule to expire them.

Edge case: Delete marker with versioning disabled

If you suspend versioning and then delete an object, the delete is permanent. No recovery.

Common mistake: Forgetting lifecycle rule applies to previous versions

By default, rules often target current versions. To clean up old versions, you must explicitly add NoncurrentVersionExpiration.

What you learned & what's next

You now understand why versioning is essential for data protection and how lifecycle rules automate cost management. You know how to enable both via console or CLI, and how to troubleshoot common issues like delete markers and slow transitions.

Key takeaways:

  • Versioning is bucket-level, can be enabled/suspended (not disabled), and preserves every object version.
  • Lifecycle rules let you transition to cheaper storage or expire objects automatically.
  • Delete markers hide objects; you must delete them to permanently remove a version.
  • Use CLI or Infrastructure as Code for repeatable configurations.
  • Combine both: versioning for safety, lifecycle for cost.

Your next step: move on to the next lesson in this AWS track, where you'll learn to manage S3 bucket policies and access controls—critical for securing your versioned buckets.

Keep building, and remember: your data is only as safe as the features you enable today.

Practice recap

Now apply what you've learned: create a new bucket, enable versioning, upload two versions of a file, and add a lifecycle rule to expire versions after 7 days. Then check the bucket's storage size to see how the rule helps. This hands-on exercise solidifies your understanding of both features.

Common mistakes

  • Enabling versioning after the damage is done—if a file was overwritten before enabling, the old version is gone forever.
  • Forgetting to add lifecycle rules for previous versions, leaving old versions to accumulate and rack up costs.
  • Assuming lifecycle rules run instantly—they only evaluate once per day, so transitions can lag by up to 48 hours.
  • Deleting an object and thinking it's gone—delete markers hide it, but versions remain until you permanently delete them.

Variations

  1. Use infrastructure as code (Terraform or CloudFormation) to manage versioning and lifecycle rules as part of your deployment pipeline.
  2. Suspend versioning instead of disabling it—old versions stay, but new uploads overwrite without creating new versions.
  3. Enable MFA delete for critical buckets to require a second authentication factor for permanent version removal.

Real-world use cases

  • Protect critical application data from accidental overwrites or deletes by enabling versioning on production buckets.
  • Automate storage cost optimization by transitioning older file versions to S3 Glacier for long-term archival.
  • Meet compliance requirements by retaining exact versions of documents and logs, with lifecycle rules that enforce retention windows.

Key takeaways

  • Versioning preserves every version of an object, providing an undo button for data loss and protection against ransomware.
  • Lifecycle rules automate transitions to cheaper storage and automatic deletion of obsolete data.
  • Delete markers hide objects—but you must delete all versions and markers to permanently remove data.
  • Enable versioning before you upload critical data; it's not retroactive.
  • Combine lifecycle rules for current and previous versions to control costs effectively.
  • Use AWS CLI or Infrastructure as Code to make configuration repeatable and auditable.

Sponsored

Sponsored

Discussion

Questions, corrections, and tips help everyone reading this page.

0 comments

Add a comment

Shown publicly with your comment.

Be constructive · max 4,000 characters

No comments yet — start the thread.

Related tutorials, quizzes, and articles for this topic.