AWS S3 Lifecycle Policy Analyzer

Read a lifecycle configuration the way the bill does. Two of these rules cost money quietly, and neither of them is visible in the console.

Paste below, or drop a file anywhere on this panel

Or drop a file anywhere on this panel. Nothing is uploaded: the analysis runs in this tab.

The answer appears here

Paste on the left and press Analyze. Nothing leaves this tab.

Examples

Real input you can load into the tool above. Each one shows a different thing going wrong, because that is what the tool is for.

Archived at 30, expired at 60

Pays for 90 days of Glacier and uses 30 of them

{
  "Rules": [
    {
      "ID": "archive",
      "Status": "Enabled",
      "Filter": { "Prefix": "logs/" },
      "Transitions": [{ "Days": 30, "StorageClass": "GLACIER" }],
      "Expiration": { "Days": 60 },
      "NoncurrentVersionExpiration": { "NoncurrentDays": 7 },
      "AbortIncompleteMultipartUpload": { "DaysAfterInitiation": 7 }
    }
  ]
}

Nothing cleans up multipart uploads

Abandoned parts billed forever and invisible in every listing

{
  "Rules": [
    {
      "ID": "expire",
      "Status": "Enabled",
      "Filter": { "Prefix": "tmp/" },
      "Expiration": { "Days": 30 },
      "NoncurrentVersionExpiration": { "NoncurrentDays": 7 }
    }
  ]
}

Expiration on a versioned bucket

Writes a delete marker and keeps every version at full price

{
  "Rules": [
    {
      "ID": "expire",
      "Status": "Enabled",
      "Filter": { "Prefix": "logs/" },
      "Expiration": { "Days": 30 },
      "AbortIncompleteMultipartUpload": { "DaysAfterInitiation": 7 }
    }
  ]
}

Common mistakes

These are the ones that fail silently. The config is accepted, nothing raises an error, and the consequence arrives later.

  1. Expiring objects shortly after archiving them

    Each storage class has a minimum billable duration charged whether or not the object lives that long, so a 30 day stay in Glacier is billed as 90.

    Instead:Either keep the object past the minimum, or skip the transition and expire straight from Standard.

  2. Adding an expiration rule to a versioned bucket and expecting the bill to fall

    Expiration writes a delete marker and keeps every previous version at full price.

    Instead:Add NoncurrentVersionExpiration, and ExpiredObjectDeleteMarker to clean up what is left.

  3. Never adding a multipart cleanup rule

    Abandoned parts are stored and billed indefinitely and are invisible in every object listing.

    Instead:Add one unfiltered rule with AbortIncompleteMultipartUpload set to 7 days, and run aws s3api list-multipart-uploads to see what is already there.

A storage class has a minimum billable duration

Glacier bills 90 days and Deep Archive bills 180, whether or not the object survives that long. Archiving at day 30 and expiring at day 60 pays for 90 days of storage and uses 30 of them.

The transition itself is a charge too

Every object moved is a request, and for a bucket of millions of small objects the transition can cost more than the storage it saves. Which is why S3 does not transition anything under 128 KB to Infrequent Access at all: the rule runs, and a bucket of small objects is untouched, exactly as documented.

Glacier adds 40 KB of billable overhead per object

8 KB at Standard rates for the name and metadata, and 32 KB at the archive rate for the index. Archiving objects smaller than that costs more than leaving them where they are, which makes aggregation the first step rather than an optimisation.

On a versioned bucket, expiration deletes nothing

It writes a delete marker. Every previous version stays at full price, the console shows the object as gone, and the bill does not move. NoncurrentVersionExpiration is the setting that actually removes data, and it is a separate line.

Incomplete multipart uploads are billed forever

Parts of an upload that never finished do not appear in the console's object list or in a bucket's object count, and nothing expires them by default. Buckets have been found holding more in abandoned parts than in objects. One rule with AbortIncompleteMultipartUpload fixes it permanently.

Overlapping rules resolve toward the lower cost

S3 does not pick one rule and ignore the other. Where two rules cover the same object, the shorter expiration and the cheaper transition win, which is rarely what somebody had in mind when they added the second rule.

Transitions only move one way

Down the chain toward colder storage. Bringing archived data back is a restore and a copy, not a lifecycle rule, and S3 rejects a configuration that tries.