Back to blog
aws s3lifecycle rulesversioningcost optimization

S3 Lifecycle Rules & Versioning: Cut Storage Costs Without Losing Data

Learn how to build lifecycle policies, manage versioning, and automate expirations with ready-to-use JSON, CLI commands, and a BucketMate macOS workflow.

Amazon S3 lifecycle rules are your best lever for shrinking storage bills while keeping every object version you still need. They let you transition infrequently accessed data into cheaper tiers, expire stale versions automatically, and enforce governance policies that align to each bucket’s workload. (See the AWS lifecycle configuration examples and multipart upload cleanup guidance for reference.)

Why lifecycle automation is a 2025 essential

Copy-paste lifecycle templates

Transition objects after 30 days, move deep archive after 90 days, keep five noncurrent versions, and clean up multipart uploads:

{
  "Rules": [
    {
      "ID": "CostOptimization",
      "Filter": {
        "Prefix": ""
      },
      "Status": "Enabled",
      "Transitions": [
        {
          "Days": 30,
          "StorageClass": "STANDARD_IA"
        },
        {
          "Days": 90,
          "StorageClass": "GLACIER_IR"
        }
      ],
      "Expiration": {
        "Days": 365
      },
      "NoncurrentVersionExpiration": {
        "NoncurrentDays": 120,
        "NewerNoncurrentVersions": 5
      },
      "AbortIncompleteMultipartUpload": {
        "DaysAfterInitiation": 7
      }
    }
  ]
}

Apply it with the AWS CLI:

aws s3api put-bucket-lifecycle-configuration \
  --bucket your-bucket-name \
  --lifecycle-configuration file://lifecycle.json

Target specific prefixes or tags when you need different retention profiles:

{
  "Rules": [
    {
      "ID": "LogsArchive",
      "Filter": {
        "And": {
          "Prefix": "logs/",
          "Tags": [
            {
              "Key": "retention",
              "Value": "short-term"
            }
          ]
        }
      },
      "Status": "Enabled",
      "Transitions": [
        {
          "Days": 14,
          "StorageClass": "STANDARD_IA"
        },
        {
          "Days": 60,
          "StorageClass": "GLACIER_IR"
        }
      ],
      "NoncurrentVersionExpiration": {
        "NoncurrentDays": 30,
        "NewerNoncurrentVersions": 3
      },
      "Expiration": {
        "Days": 120
      }
    }
  ]
}

These examples use Glacier Instant Retrieval for fast restores. If you need deeper cost cuts and can tolerate hours-long recovery, swap in GLACIER or DEEP_ARCHIVE (see the Glacier Instant Retrieval launch brief for tradeoffs).

Interactive lifecycle builder and cost forecaster

Tune your transition timeline, noncurrent retention, and tier mix-then copy the JSON and CLI command that match your inputs:

Dataset size5.0 TB
Active data share40%
Infrequent access share40%
Cold archive share20%
Baseline cost$117.76
Optimized cost$76.80
Projected monthly savings$40.96
Hot tier$47.10 at 0.023/GB
Standard-IA tier$25.60 at 0.0125/GB
Glacier IR tier$4.10 at 0.004/GB
Lifecycle JSON
{
  "Rules": [
    {
      "ID": "CostOptimization",
      "Filter": {
        "Prefix": ""
      },
      "Status": "Enabled",
      "Transitions": [
        {
          "Days": 30,
          "StorageClass": "STANDARD_IA"
        },
        {
          "Days": 90,
          "StorageClass": "GLACIER_IR"
        }
      ],
      "Expiration": {
        "Days": 365
      },
      "NoncurrentVersionExpiration": {
        "NoncurrentDays": 120,
        "NewerNoncurrentVersions": 5
      },
      "AbortIncompleteMultipartUpload": {
        "DaysAfterInitiation": 7
      }
    }
  ]
}
CLI command
aws s3api put-bucket-lifecycle-configuration --bucket your-bucket-name --lifecycle-configuration '{ "Rules": [ { "ID": "CostOptimization", "Filter": { "Prefix": "" }, "Status": "Enabled", "Transitions": [ { "Days": 30, "StorageClass": "STANDARD_IA" }, { "Days": 90, "StorageClass": "GLACIER_IR" } ], "Expiration": { "Days": 365 }, "NoncurrentVersionExpiration": { "NoncurrentDays": 120, "NewerNoncurrentVersions": 5 }, "AbortIncompleteMultipartUpload": { "DaysAfterInitiation": 7 } } ] }'

The planner estimates monthly savings by comparing your hot-tier-only cost against a blended lifecycle layout using current AWS rate-card examples. Adjust the sliders until the projected savings and retention requirements line up, then paste the generated payload into aws s3api or your IaC templates. (See AWS cost estimation guidance and Standard-IA announcement.)

Versioning strategies that avoid runaway bills

  1. Keep versioning on for durability, but shorten noncurrent retention. Setting NoncurrentVersionExpiration to 30–180 days preserves rollback windows without growing storage indefinitely (Lifecycle configuration examples).
  2. Limit how many noncurrent versions persist. Retaining the five newest noncurrent versions protects recent edits while purging ancient ones that rarely get restored (Noncurrent version expiration API reference).
  3. Remove expired delete markers automatically. This prevents accidental empty-object responses when a current version was already deleted and keeps your bucket listing clean for tooling (Lifecycle configuration examples).
  4. Abort incomplete multipart uploads. Large transfers that stall mid-way can otherwise hold terabytes of billable fragments; setting a seven-day cutoff is a safe default (Multipart upload lifecycle rule).

BucketMate on macOS: applying the policy without scripts

  1. Open BucketMate, connect to your AWS profile, and select the target bucket in the left pane.
  2. Click Lifecycle & Versioning, then choose Import JSON and paste the policy generated above.
  3. Confirm the rule scope (whole bucket vs. prefix) and press Apply; BucketMate updates the bucket via the AWS API and shows a success toast when the configuration is live.
  4. Switch to the Versions tab to verify the expected retention count and ensure delete markers or stale versions are scheduled for cleanup.
  5. Revisit the view after a lifecycle run (typically within 24 hours) to confirm objects have transitioned and the bucket size chart trends downward.

Because you ran everything through the app, your team gets a repeatable macOS workflow with audit-friendly change tracking, and you can export the same JSON into Terraform or CloudFormation for infrastructure parity.

Next actions

  • Schedule Storage Lens reports after 48 hours to validate that noncurrent version counts trend toward your target (Lifecycle configuration examples).
  • Use AWS Config or EventBridge rules to alert when lifecycle rules drift from the approved settings, ensuring cost and compliance stay aligned (Lifecycle configuration examples).

Sources

Have questions? Please contact us 👇

Contact Us