Streaks
Consistent-daily-activity counters that reward habit, not volume.
A streak is a counter that ticks once per UTC day when a given event fires. If the user skips a day, the counter burns. At configured milestones, a streak awards bonus coins, tokens, or badges.
Why streaks exist
Coins reward each action; streaks reward showing up. A well-placed streak is often the single biggest retention lever in a gamification economy.
How they work
- Bound to one event type (the "today's activity" signal).
- One tick per UTC day maximum.
- Hatched fires
streak.milestonewebhooks at[7, 14, 30, 60, 90, 180, 365]by default (configurable). - Missing a day resets to zero unless a grace token is available.
Example
daily_lesson streak — +5 coins every tick day, +50 bonus at 7 days, +200 + 1 premium token at 30 days. Awards a "Week Warrior" badge at 7 days that shows off in the widget.
How to set it up
- Pick the event type that counts as "today's activity".
- Set a per-day bonus (optional).
- Add milestone bonuses for the thresholds that matter to you.
- Copy the streak
keyfrom Dashboard → Streaks. - Pick a display mode —
count,row, ormini(a bare inline🔥 Nchip for navbars and menus). - Mount the streak widget with
data-streak-key="…"(and optionallydata-display-mode="mini").
The streak key is the stable workspace-level identifier for one streak
definition, such as daily_lesson. It is not generated by the widget and it
does not come from the user's buddy state. Treat it like app configuration:
hardcode it in a shared constant, store it in an environment variable such as
NEXT_PUBLIC_HATCHED_STREAK_KEY, or pass different keys to different streak
mounts when you intentionally show multiple counters.
Gotchas
- Streaks tick in UTC. Multi-timezone products may see users "burn" during their night. If this matters, model your own tick event instead of using a daily_login heuristic.
- No grace days are built in — if you need them, grant a freeze token the user can burn.
Related
- Badges — milestone streaks usually award one.
- Leaderboard — rank by streaks completed.
- Streak widget — rendering a streak with
data-streak-key. - Configure rules — picking the event and milestones.