# Streaks

> Consistent-daily-activity counters that reward habit, not volume.

Source: https://docs.hatched.live/docs/concepts/streaks

A streak is a counter that ticks once per period — once per UTC day, once per
ISO week, or once per calendar month, depending on the streak's `period`
(`daily`, `weekly`, or `monthly`). If the user misses a period, 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 period maximum — per UTC day for `daily`, per ISO week for
  `weekly`, per calendar month for `monthly`.
- Milestones are tenant-configured and default to none (an empty list), so no
  `streak.milestone` webhook fires until you set milestones in
  Dashboard → Streaks.
- Missing a period 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

1. Pick the event type that counts as "today's activity".
2. Set a per-day bonus (optional).
3. Add milestone bonuses for the thresholds that matter to you.
4. Copy the streak `key` from Dashboard → Streaks.
5. Pick a display mode — `count`, `row`, or `mini` (a bare inline `🔥 N` chip
   for navbars and menus).
6. Mount the [streak widget](/docs/reference/widgets/streak) with
   `data-streak-key="…"` (and optionally `data-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](/docs/concepts/badges) — milestone streaks usually award one.
- [Leaderboard](/docs/concepts/leaderboard) — rank by streaks completed.
- [Streak widget](/docs/reference/widgets/streak) — rendering a streak with `data-streak-key`.
- [Configure rules](/docs/guides/configure-rules) — picking the event and milestones.
