← Blog
Cream file folder with an orange hourglass and sage-green tab on a lavender background.
Published on
2026-10-29

S3 lifecycle policy: transitions, expiration, and versioning

An S3 lifecycle policy defines when Amazon S3 should move stored objects to another storage class or expire them. A useful policy starts with the data: how long people need it, how quickly they must retrieve it, and what can be permanently removed.

This guide covers general-purpose S3 buckets, a scoped JSON example, and the checks to make before enabling a rule. For the broader storage options, see our Amazon cloud storage guide.

What an S3 lifecycle policy controls

A bucket has a lifecycle configuration containing one or more rules. Each rule identifies matching objects, has an enabled or disabled status, and specifies actions. S3 Lifecycle supports transitions between storage classes and expiration actions. Separate actions handle noncurrent versions and incomplete multipart uploads.

Start with a concrete requirement such as keeping application exports readily available for a month, archiving them afterward, and deleting them when their approved retention period ends. Those periods should come from the data owner. Copying another team's settings can remove files your application still needs.

Scope lifecycle rules before choosing dates

Use a specific prefix, object tags, object size, or an appropriate combination to identify objects. A prefix matches the beginning of an object key; it is not a separate filesystem directory. For example, lifecycle-demo/archive/ matches lifecycle-demo/archive/export.csv.

The lifecycle configuration elements define how filters combine. An empty filter applies across the bucket. When combining a prefix with tags or size limits, use the documented And structure rather than assuming that separate fields create an alternative match.

Rules apply to existing objects as well as new uploads. A newly enabled 30-day expiration rule can make matching files that are already older than 30 days eligible for removal. List the matching keys and versions before enabling it, and check representative filenames with the application owner.

Choose transitions around retrieval and total cost

A transition changes where an object is stored within S3's storage classes. It does not move the object into a separate backup system. Check the storage class comparison against the workload:

  • S3 Standard-IA: infrequent access with immediate retrieval, retrieval charges, and a 30-day minimum storage duration.
  • S3 Glacier Instant Retrieval: immediate access for rarely read data, with a 90-day minimum.
  • S3 Glacier Flexible Retrieval: archived data that requires restoration before access, with a 90-day minimum.
  • S3 Glacier Deep Archive: longer-term archives requiring restoration, with a 180-day minimum.

Minimum storage duration is a billing condition, not a promise to retain data. Include transition requests, retrieval, restoration, and early-deletion charges in the estimate. Moving a file repeatedly can cost more than leaving it where it is.

The minimum billable duration also differs from the waiting period before a transition. On July 16, 2026, AWS removed the 30-day wait for transitions from S3 Standard to Standard-IA and One Zone-IA. The 30-day transition in the example below is a chosen schedule, not a current mandatory wait.

For changing access patterns, evaluate S3 Intelligent-Tiering separately. Its access-based tiering differs from a lifecycle rule based on object age. Before adopting archival tiers, test the time until the application can use a restored file, including its own processing.

The small-object transition default

Under the current default, lifecycle transitions exclude objects smaller than 128 KB. AWS changed this behavior in September 2024. Older configurations can retain earlier behavior until modified. Custom size filters and the API's transition-default setting can change the result.

That threshold concerns transitions; it does not protect small objects from a matching expiration rule. Check object counts as well as total gigabytes when estimating costs. A dataset containing millions of small files has a different request profile from a few large archives.

S3 lifecycle policy example for a test prefix

The following JSON is for a disposable general-purpose test bucket where versioning has never been enabled. Use only files you can lose. The first rule transitions matching objects to Standard-IA after 30 days, then Glacier Flexible Retrieval after 90 days, and expires them after 365 days. These are illustrative ages, not recommended retention periods for customer data.

The second rule cleans up incomplete uploads under the demonstration prefix. Save the configuration as lifecycle.json if you use it with an AWS SDK or CLI. AWS also provides examples of transition and expiration rules.

{
  "Rules": [
    {
      "ID": "demo-archive-and-expire",
      "Status": "Enabled",
      "Filter": {"Prefix": "lifecycle-demo/archive/"},
      "Transitions": [
        {"Days": 30, "StorageClass": "STANDARD_IA"},
        {"Days": 90, "StorageClass": "GLACIER"}
      ],
      "Expiration": {"Days": 365}
    },
    {
      "ID": "demo-abort-incomplete-uploads",
      "Status": "Enabled",
      "Filter": {"Prefix": "lifecycle-demo/"},
      "AbortIncompleteMultipartUpload": {"DaysAfterInitiation": 7}
    }
  ]
}

All three ages in the first rule are measured from object creation, rather than from the previous transition. The second rule measures time from upload initiation. Ordinary object expiration does not remove unfinished multipart uploads, and aborting unfinished uploads does not delete completed objects. Choose a cleanup interval longer than legitimate uploads need. See AWS's multipart cleanup guidance.

The example was parsed and checked locally against the Botocore request schema. It was not applied to an AWS bucket; actual transitions, permissions, billing, and deletion timing still require an isolated test.

Versioning changes what expiration means

Check bucket versioning before adapting this example. In an unversioned bucket, expiration permanently removes the object. In a bucket with versioning enabled, ordinary expiration leaves the data version behind. S3 puts a delete marker in its place as the current version, and the data version becomes noncurrent. The bytes can remain stored and billable.

A NoncurrentVersionExpiration action can permanently delete older versions. Its age is measured from when a version became noncurrent, not its original upload. Adding NewerNoncurrentVersions makes the retained-version count another condition; both the age and count conditions must be met. Review the expiration behavior and the noncurrent-version action before using it.

Suspending versioning does not return a bucket to its never-versioned behavior. A null-version object can be permanently removed by expiration. Keep that case out of an initial experiment.

Apply and verify a lifecycle configuration

  1. Inspect the bucket: confirm the account, Region, versioning state, existing rules, matching objects, and retention requirements.
  2. Save the current configuration: keep a reviewed copy before changing it. The PutBucketLifecycleConfiguration API replaces the existing configuration; it does not append a rule. Include every rule you intend to retain.
  3. Use the test bucket first: in the AWS Management Console, open the bucket's Management tab and create a lifecycle rule with the intended prefix and actions. Inspect the scope before enabling it.
  4. Read the saved rules back: confirm the prefixes, status, ages, and storage classes. A successful save proves configuration acceptance, not that any object has transitioned.
  5. Verify the outcome: inspect storage classes, versions, delete markers, and unfinished uploads. Test retrieval after a transition and record the result before expanding the scope.

For a read-only configuration check with the AWS CLI, replace the placeholder with your test bucket name:

aws s3api get-bucket-lifecycle-configuration --bucket YOUR_PRIVATE_TEST_BUCKET

The configuration read API needs the appropriate permission. Protect permission to change lifecycle settings separately: denying ordinary object deletion through a bucket policy does not stop an already configured lifecycle expiration.

When a rule appears not to work

Check the prefix, status, object age, size, current storage class, and bucket versioning first. AWS calculates day-based eligibility using UTC boundaries, and lifecycle execution is asynchronous. An eligibility date is not an exact deletion appointment.

Also inspect conflicting rules, replication status, and Object Lock retention or legal holds. These can affect which actions are eligible. Use the AWS lifecycle troubleshooting guide rather than repeatedly shortening an expiration period until files disappear.

For application storage, assign an owner to each rule and record why the selected files can be archived or removed. Our cloud storage for applications guide covers the surrounding access, recovery, and integration decisions. S3 API compatibility alone does not establish that another provider implements these lifecycle actions.

Common questions

Does a lifecycle policy replace a bucket policy?

No. A lifecycle configuration schedules storage actions. A bucket policy controls access. Review both when deciding who can change or remove data.

Can disabling a rule recover deleted files?

No. Disabling a rule does not restore a permanently deleted object or version. Keep recovery copies and test their restoration independently.

Can this example be used for an S3 directory bucket?

No. Directory buckets support a narrower lifecycle feature set, including expiration and cancellation of incomplete uploads, but not the storage-class transitions in this example. Use the bucket-specific API documentation.

Your next workload belongs on Hivenet.

Pick one AI, compute, or storage workload and see the difference for yourself. Spin it up in minutes, or let our team map your fastest path to production.