Habit loops: Cadence first, triggers and streaks second
There is a question to answer before designing a single notification: how often does someone genuinely need this product?
Not how often you would like them to open it. How often the underlying job actually recurs. A language learner benefits from practicing today and again tomorrow. Someone running payroll does not benefit from thinking about payroll on a Tuesday afternoon in the middle of the month.
There is a prior condition too, and it is the one worth settling first: a loop cannot form around value that has not landed yet. Until someone has reached a first real outcome, a notification is asking them to repeat something they never got anything out of. Habit work belongs after activation, not instead of it.
Habit mechanics amplify a cadence that already exists. They cannot manufacture one, and the attempts tend to produce the same result: engagement metrics that improve while the people behind them get quietly annoyed with you.
What is a habit loop?
A habit loop is a repeating cycle of trigger, action, variable reward and investment, run often enough that returning stops being a decision. The variation is essential, not decoration. The formulation is the Hook Model, set out by Nir Eyal with Ryan Hoover in Hooked (2014), and it is the standard vocabulary for this pattern.1
Each step does a distinct job:
- The trigger starts the cycle. External at first (a notification, an email), internal later (the feeling that prompts you to check something without being asked).
- The action is the behavior you want, made as small as it can usefully be.
- The reward resolves whatever the trigger raised, and works better when it varies. A payoff you can predict exactly stops registering.
- The investment is the part the user leaves behind: accumulated history, configuration, a streak, a graph. It is what makes the next trigger land harder.
The order is not arbitrary, and neither is the emphasis, which brings us to the thing teams get backwards.
Investment is the only step that survives a broken routine
You can build a trigger and a reward that both work, and still lose them: they hold while a routine holds and evaporate the moment it breaks. Someone takes a vacation, changes jobs, has a bad couple of weeks. When they come back, the notifications are noise and the rewards are meaningless, because the loop they were reinforcing is gone.
What brings that person back is whatever they had already built up. Two hundred days of a streak they do not want to forfeit. A year of contribution history that would restart at zero somewhere else. A workspace configured exactly the way they think.
So the accumulation layer is not the last step of the loop; it is the only durable one. Which is the opposite of how effort usually gets allocated, spending months on notification timing and copy while nothing in the product gets more valuable the longer you use it.
Other people are a variance source most B2B products already have. A leaderboard, a team activity feed, a visible record of what colleagues have done changes on its own between visits, supplies social accountability, and costs nothing to generate because your users produce it. Fitness and learning products lean on this hardest (live rankings, leagues, friends’ activity), and the mechanism transfers directly to any product where colleagues can see each other’s work.
Loss aversion is the strongest and the most dangerous lever
A user protecting a streak is avoiding a loss, and people feel a loss more sharply than they feel an equivalent gain, which is the loss aversion described by Daniel Kahneman and Amos Tversky in their 1979 work on prospect theory, and which reverse trials exploit at the point of payment.2 The size of the effect has been contested since, so treat it as a real asymmetry of uncertain magnitude, not a law.
It is also why this is the pattern most easily turned against the person using it. A streak on a product someone genuinely wants to use daily is a service. The same streak on a product they need twice a month is a small manufactured anxiety, and it will produce return visits, better numbers, and a user who resents you.
The test is simple: would the user be glad you sent this, or does it work because they feel bad? A grace mechanic (a streak you can freeze, protect or repair) is the usual sign a team has noticed the difference, because it deliberately weakens the punishment without weakening the accumulation.
The three shapes of accumulation
| Shape | What builds up | Why it holds |
|---|---|---|
| A record | Consecutive days, sessions, or a visible history | Restarting from zero is a real loss, and the number is legible |
| Configuration | Views, automations, templates, workspace structure | Rebuilding it is work the user has already paid for once |
| Standing | A public profile, a reputation, a visible track record | It has value outside your product, sometimes career value |
A record has a property that configuration and standing both lack: it can trigger by being empty, and if it is public it doubles as something the user will show off on purpose. A visible gap where activity should be pulls harder than a reward for filling it, which is unusual here: every other mechanic on this page runs on positive reinforcement. Used carelessly it is also the fastest route to the resentment problem described above.
Standing is the strongest of the three and the rarest, because it means leaving costs the user something in the world, not only inside your software. The scale this can reach is worth registering: GitHub reported more than 5.2 billion contributions to over 518 million projects during 2024, much of it on public work where the record is visible to anyone who looks.3 Nobody built that by sending reminders. A developer’s public contribution history is the clean case: it functions as evidence about them, to people who are not you, which makes it an artifact that travels as well as a switching cost. It is the same bargain a community offers a contributor: do something visible here and it accrues to your name, not only to ours.
Configuration is the one most products can actually build. Every custom view a user makes is a small piece of the product they built themselves, which is the same mechanism as data lock-in arriving through effort rather than storage.
Products with no rhythm to amplify
| The trigger | Habit forms | Just reminders |
|---|---|---|
| Natural cadence | The job genuinely recurs daily or weekly | Monthly, quarterly, or event-driven |
| Session length | Useful in a couple of minutes | Needs an uninterrupted hour |
| Accumulation | Something gets better with use | Every session starts from the same place |
| Reward variance | Outcomes differ visit to visit | Identical result every time |
A cadence only forms where the underlying work already repeats: learning and practice tools (Duolingo, Anki), fitness and activity tracking, team communication where other people are waiting (Slack), developer tools with a public record (GitHub), and task systems people live in all day. What they share is not gamification. It is that a reasonable person would want to return that often anyway.
Notifications, and the cost of one too many
Every trigger you send spends a small amount of permission. Send more than the value justifies and people do not merely ignore you; they disable the channel, permanently, and you cannot get it back.
Three rules that need no benchmark:
- Match frequency to the cadence you established above. Daily notifications for a weekly product train people to ignore you, which costs you the weekly trigger you actually needed.
- Time the trigger for when the action is possible, not when attention is highest. A prompt that arrives when someone cannot act gets dismissed, and dismissal is a habit too.
- Make the first one earn the second. Notification permission is the most easily destroyed asset in the product, and the disable rate is worth watching as closely as the click rate.
Published disable-rate figures circulate widely for this and none of them survive checking, so measure your own: send less than you think, then watch opt-outs and return rate together, not separately.4
Signals that a habit is forming
Watch the gap between sessions for a single cohort. Shrinking intervals are the only directly observable form of a habit forming. Total sessions cannot tell you the same thing, because they rise whenever you acquire more people.
Then split return visits by whether a notification preceded them. Unprompted returns are the real measure of an internal trigger, and the number is usually humbling. Check too whether your accumulation layer predicts anything: compare people who built up a lot against people who built up little at the same tenure, and if they retain identically, the thing you are accumulating is not valued and the loop is running on triggers alone.
The question underneath all of it is what happens to someone who misses a week. A loop that recovers them is a habit. One that loses them was a routine you were maintaining on their behalf.
Start with the cadence
Write down the honest cadence of the underlying job, in one sentence. Everything above depends on it, and getting it wrong does not leave you neutral: it makes every decision after it worse.
Then name what accumulates. If nothing does, build that before you touch a single notification. It is the slower work, the least visible, and the only part that survives a bad month.
The rest is subtraction and one addition. Shrink the action until it fits a gap in somebody’s day, because a loop needing fifteen uninterrupted minutes gets deferred until it is forgotten. Add one thing that genuinely varies between visits, which in B2B is almost always other people’s activity and never a random reward. Cut one notification and watch opt-outs and unprompted returns; the marginal notification is usually costing you the channel.
Two checks before you call it done. Does the loop move the reasons people actually leave, or only the return numbers? And does it work for any reason other than that missing it feels bad? A mechanic running purely on that, attached to a product nobody wanted daily, is a way to lose people slowly.
Notice what the durable half of a habit loop actually was: not the trigger, not the reward, but the pile of stuff a long-time user has built up and does not want to lose. That is a bigger idea than habit, and it works on products with no rhythm at all. What accumulates inside an account is the quietest retention mechanism in this section and the one competitors find hardest to answer.
Footnotes
-
Nir Eyal with Ryan Hoover, Hooked: How to Build Habit-Forming Products (2014), which is where the trigger-action-variable reward-investment sequence and the external-to-internal trigger progression come from. The model is his; the argument on this page about cadence and about investment being the durable step is not. ↩
-
Daniel Kahneman and Amos Tversky, “Prospect Theory: An Analysis of Decision under Risk” (Econometrica, 1979), which is where loss aversion comes from. Its magnitude, and the frequently repeated “losses hurt twice as much as gains feel good,” have been challenged in later work, so this page claims the direction of the effect and not a multiple. ↩
-
GitHub, Octoverse 2024, company-published: “more than 5.2 billion contributions to more than 518 million open source, public, and private projects” during 2024, and 1.4 million developers making a first open-source contribution. Quoted as evidence that a cumulative public record operates at very large scale, which is all it shows: GitHub publishes no figure connecting contribution graphs to retention, and none is implied here. ↩
-
The figures usually attached to this pattern do not survive checking. “Duolingo went from 12% to 55% retention with streaks” traces to gamification-vendor blog posts citing each other, with no Duolingo disclosure behind it, and it was live in this page’s own meta description before being removed. Duolingo is a public company and reports engagement in its shareholder letters, so a sourced figure may exist; none is quoted here because we could not read it directly. The same applies to the widely circulated push-notification disable rates. ↩