skip to content

A transition rule with a thirty-day age has not moved an object on day 31 — why might that be?

level: middleimportance: nice to knowfreq 28%

answer

  1. a condition, not a timer
  2. eligible and moved are different moments
  3. the sweep runs on its own cadence
  4. or the filter never matched at all
  5. has anything under it ever moved?

basics

~20 s

Lifecycle rules are evaluated asynchronously on the provider's own schedule, so an object becomes eligible at the age and moves some time afterwards. The other common cause is a filter mismatch: the object's key never matched the rule.

solid answer

~50 s

Two causes cover nearly every case. First, **evaluation lag**: a lifecycle rule is not a trigger fired the moment an object crosses the age. A background process sweeps the store periodically, marks eligible objects and transitions them, so eligibility and execution are different moments and a day or two of drift is normal. Second, a **filter mismatch**: the rule applies to a path prefix or a tag, and objects written under a slightly different prefix are simply never in scope — a silent no-op that looks identical to lag until you check. Distinguish them by age: if objects written weeks earlier under the same prefix did transition, it is lag; if none of them ever have, it is the filter. Expiration rules drift the same way, so retention deletions can lag their stated age too.

go deeper

for a junior

Recall that a lifecycle rule is a condition swept periodically, so an object moves at or after its age rather than exactly on it.

for a middle

Explain both causes — asynchronous evaluation and a filter that never matched — and the one question that separates them.

for a senior

Anticipate the one-off cost when a rule is first enabled over an existing archive, and know that an expiration rule is best-effort relative to its stated day.

for a principal

Where retention is a legal commitment rather than a cost lever, state the best-effort gap in the control description instead of letting an assessment discover it.

## A rule is a policy, not a timer It is tempting to read `afterDays: 30` as a scheduled event attached to each object. It is not. A lifecycle rule declares a **condition** — objects under this filter, older than this age, belong in that tier — and the store runs an asynchronous process that periodically finds objects matching the condition and acts on them. Two consequences follow immediately: - **Eligibility and execution are different moments.** An object is eligible on day 30 and is actually transitioned when the sweep next reaches it. A lag of hours to a couple of days is normal operation, not a fault. - **The saving starts when the object moves**, not when it became eligible, so a cost forecast built on exact ages is slightly optimistic. Over a large archive the drift is a rounding error; over a short-lived object with a tight transition age it is not. Providers differ in how they present this — in the sweep cadence, and in whether the new tier's charging is anchored to the eligibility moment or to the move — so the safe assumption is only that the move happens *at or after* the stated age, never before. ## The second cause, which looks identical The other reason an object does not move is that **the rule never applied to it**. Lifecycle rules are scoped by a filter — typically a key prefix, sometimes tags, sometimes a size condition. Anything not matching is out of scope, silently: - a writer emitting under `logs-archive/` while the rule filters `logs/`; - a trailing-slash or case difference in the prefix; - a tag the rule requires that the writer stopped setting; - objects excluded by a minimum or maximum size condition on the rule. Nothing errors. The rule reports itself as enabled, the objects stay warm, and the cost saving quietly never arrives. This failure is far more expensive than lag because it does not resolve itself. ## Telling them apart | Observation | Likely cause | |---|---| | Objects a few days past the age are still warm, older ones have moved | Evaluation lag | | No object under that prefix has ever moved, at any age | Filter mismatch | | One writer's objects move, another's never do | Filter mismatch on the other writer's key or tags | | Moves happen but cluster on particular days | Normal sweep cadence | The diagnostic is one question: **has anything under this filter ever transitioned?** If yes, wait. If no, read the filter against a real object key, character by character. ## Other things that make the age surprising - **Age is measured from when the object was written**, not from when the rule was created and not from when the object was last read. A rule added today applies to objects that already exist and are already old; they will be swept and moved on the next pass, which can produce a large one-off transition fee the day a rule is enabled. - **Rewriting an object resets its age**, because the age belongs to the object that is there now. A pipeline that rewrites its output nightly will never let anything reach a transition age. - **Enabling and disabling a rule does not undo past actions.** Turning a transition rule off leaves already-moved objects where they are, with their minimum storage duration intact. ## Why any of this matters On its own, a day of drift is uninteresting. It matters in two places. The first is an invoice investigation: "the rule has been on for a week and the bill has not moved" is answered either by "give it another sweep" or by "the rule has never matched anything", and those lead to completely different work. The second is a retention commitment: if a policy says data is deleted at ninety days, an expiration rule is a best-effort mechanism that deletes *at or shortly after* ninety days. Where the commitment is legal rather than economic, that gap is worth knowing about and stating, rather than discovering during an assessment.

  • How do you tell evaluation lag from a filter that never matches?
    Ask whether anything under that filter has ever transitioned. If objects well past the age have moved and only the newest eligible ones have not, it is lag and it resolves itself. If nothing under the prefix has ever moved at any age, compare the rule's filter against a real object key exactly — prefix, case, trailing slash, required tags.
  • What happens to objects that were already older than the age when the rule was created?
    They are in scope immediately, because age is measured from when the object was written, not from when the rule appeared. The first sweep after enabling a rule can therefore transition a very large batch at once and produce a one-off per-object transition fee that dwarfs a normal month.
  • Does this drift also affect expiration rules used for retention?
    Yes. An expiration rule deletes at or shortly after the stated age, on the same asynchronous sweep. For an economic retention target that is irrelevant; for a commitment that data will not exist beyond a fixed day, the gap should be stated explicitly rather than assumed away.

saying these in an interview costs you the question

  • Expects the transition to happen at the exact moment of the age
  • Assumes a new rule only applies to objects written after it
  • Thinks age is measured from the object's last read
  • Treats a silently non-matching filter as impossible because the rule is enabled
  • Believes disabling a rule returns already-moved objects to the warm tier