PLG OS

Implementation worksheet · 5 min read

A Streak Freeze and Recovery Product Policy

Write four rules before shipping a streak: the grace window (how late an action still counts for yesterday — typically a few hours past local midnight), the freeze allowance (how many missed days a user can absorb, how they are earned, and whether they apply automatically), the recovery path (what happens after a break — reset to zero, restore on return within N days, or keep a longest-streak record alongside the current one), and the timezone rule (streaks are evaluated in the user's local day, fixed at their profile timezone, not the server's). Streaks exist to reward returning, so a policy that punishes a single missed day in a way the user experiences as unfair converts your most engaged cohort into churn.

A streak is the one mechanic that creates loss aversion deliberately, which means the break is a designed moment rather than an edge case. Teams design the accumulation carefully and leave the break to whatever the code happens to do.

Put it into practice

1. Set the grace window in local time

An action at 00:30 local counts for the previous day if your grace window is three hours. Without one, timezone travellers and night owls lose streaks they behaviourally earned — the most annoying possible way to lose one.

2. Decide how freezes are earned and spent

Earned by consistency (one per seven-day run), granted on a plan, or bought. Then decide whether they apply automatically on a miss or must be activated in advance — automatic is kinder and harder to reason about; explicit is clearer and less forgiving.

3. Design the break, not just the streak

Three options: hard reset, restore-on-return within N days, or current-plus-longest. Whichever you choose, show the longest streak somewhere permanent — it preserves the sense of accomplishment that a reset otherwise erases entirely.

4. Fix the timezone at the profile, not the request

Evaluate in the user's stored timezone. Deriving it per request means a trip abroad silently shifts what 'today' means and can break a streak mid-flight, which reads as a bug because it is one.

5. Test the boundaries explicitly

Action at 23:59 and at 00:01 local, a day skipped with and without a freeze available, a timezone change mid-streak, and a DST transition. Four tests; each one is a real user in production.

Streak policy

Copy this structure into your review document and record your observed result for each row.

Streak policy
RuleOptionsChosenWhy
Grace window0 / 3h / 6h past local midnight
Freeze allowancenone / earned / granted / purchased
Freeze applicationautomatic / explicit
After a breakreset / restore within N days / keep longest
Timezone sourceprofile / request / accountprofiletravel must not break a streak

A failure worth checking

The unfair-break churn: a user with a 60-day streak crosses a timezone, the server evaluates in UTC, and the streak resets while they are asleep. They were not less engaged; they flew somewhere. The support ticket reads as a bug report and the behaviour change reads as churn, and both are downstream of a policy that never considered local time.

Common questions

Should streaks reset at all?

Something has to distinguish a current streak from a historical one, or the number stops meaning anything. Keeping both — current and longest — preserves the signal without making a single miss feel like deletion.

Do freezes undermine the mechanic?

Sparingly, no: a limited freeze earned through consistency keeps the incentive while removing the cruelty of one bad day. Unlimited freezes remove the mechanic entirely, which is its own answer.

Basis and scope

This is a proposed implementation method using illustrative examples, not a measured benchmark or a customer case study. Prepared with AI assistance. Validate product-specific behavior against current documentation and your own test environment.

Continue with PLG OS

Explore onboarding →