Writing an object straight into DEEP_ARCHIVE works when you already know it is cold. But most data does not start cold - it starts warm, gets read for a while, and cools off over weeks or months. Re-tiering it by hand does not scale.
Lifecycle transitions solve this. You declare, once, that objects move into cheaper archival classes as they age, and S3 enforces the policy continuously with no code running on your side. This page shows how to write those transition rules with the SDK, how to chain them so data cools in stages, and the gotchas that catch people.
A lifecycle configuration is an array of rules, each with a Filter, a Status, and actions. A Transition names a Days age and a target StorageClass. S3 evaluates rules asynchronously - typically once a day - so an object crosses its transition boundary within about a day of the threshold, not to the exact second.
One rule can carry several transitions, moving an object into progressively colder classes over time. A common shape is Standard, then STANDARD_IA around 30 days, then GLACIER_IR or GLACIER around 90, then DEEP_ARCHIVE for long-term retention. You transition forward through the cost curve; lifecycle does not move objects back to warmer classes.
Transitions are one-directional toward colder, cheaper classes - there is no warm-up transition.
Each destination class carries a minimum storage duration (90 days for Glacier classes, 180 for Deep Archive), so back-to-back transitions still owe the minimums.
STANDARD_IA bills a 128 KB minimum object size, so tiering many tiny objects can cost more than leaving them warm.
A single PutBucketLifecycleConfiguration overwrites the whole configuration - read, modify, and write the full set to change one rule.
Use lifecycle transitions for data that starts warm and cools with age. For data you already know is cold at write time, skip the wait and set StorageClass directly on put_object - it lands in the archival class immediately, with no transition delay and no transition request fee.
Put replaces, it does not append - a second PutBucketLifecycleConfiguration wipes the previous rules. Fix: read the current config, edit it, and put the complete set back.
Expecting instant transitions - rules run about once a day, so a change is not exactly at the day boundary. Fix: treat thresholds as "within a day" and verify with GetBucketLifecycleConfiguration.
Tiering tiny objects into IA or Glacier - minimum object sizes and durations can make small files cost more archived. Fix: keep small, short-lived objects in Standard, or use Intelligent-Tiering.
Deleting before the minimum duration - transitioning to Glacier then deleting early still bills the class minimum. Fix: only transition objects that will outlive the destination's minimum.
Assuming lifecycle warms objects back up - transitions only go colder; there is no automatic un-archive. Fix: restore with restore_object when you need a cold object read.
Filter shape confusion - combining a prefix and tags needs an And wrapper. Fix: use Filter.And with Prefix and Tags for multi-condition rules.
How do I make S3 archive objects automatically as they age?
Set a lifecycle rule with a Transitions array via PutBucketLifecycleConfiguration, naming a Days age and an archival StorageClass such as GLACIER or DEEP_ARCHIVE. S3 runs the policy for you - no cron job needed.
Can one rule transition through several classes?
Yes. A single rule's Transitions array can chain multiple steps - for example STANDARD_IA at 30 days, GLACIER_IR at 90, and DEEP_ARCHIVE at 365 - cooling the object stage by stage.
Why did applying a new rule delete my other rules?
PutBucketLifecycleConfiguration replaces the entire configuration; it is not additive. Read the current rules with GetBucketLifecycleConfiguration, add or edit, and send the complete set back every time.
How quickly does a transition happen?
Asynchronously, usually within a day of the object reaching the threshold age. S3 processes lifecycle actions in a roughly daily batch, so it is never to-the-second.
Should I use lifecycle transitions or write the class directly?
Use transitions for data that starts warm and cools over time. If the object is already cold when you write it, set StorageClass directly on put_object to skip the transition delay and its per-object request fee.
Can lifecycle move an object back to a warmer class?
No. Transitions only go toward colder, cheaper classes. To read a cold GLACIER or DEEP_ARCHIVE object, issue a restore_object to stage a temporary readable copy - lifecycle will not un-archive it.
Why did tiering small files raise my bill?
STANDARD_IA and Glacier classes apply minimum object sizes (128 KB for IA) and minimum storage durations. Many tiny or short-lived objects can cost more tiered than left in Standard. Use Intelligent-Tiering or leave them warm.
Can I target objects by tag instead of prefix?
Yes. A Filter can match a prefix, a tag, or both. To combine conditions, wrap them in Filter.And with Prefix and Tags.