Back to blog

A push notification rulebook

I’m revamping our push notifications and decided to dig into what’s already working for others.

This is mostly a post for self, but hopefully it’s helpful for you as well.

Insights from platform engineering blogs, marketing research, Reddit behaviour threads, and Duolingo’s published notification AI system.

Now, let’s get into it.

The title is the hook. The body earns the tap.

That sequencing matters because the most important words need to land first. Even if the copy gets cut off, the value should still be clear. Good morning is a wasted slot. Ask for that referral does a job.

Write for the glance, not the scroll

On length, the research is consistent: 20-90 characters tends to produce the strongest click-through rates. In practice, think two lines and roughly 12-15 words. Beyond that, you are usually writing for yourself, not for the user.

Use active voice. Attention is limited, so people should be able to decide in one glance whether the message is useful. The moment the notification becomes about your brand or your feature, it starts to lose power. Write about what the user gets.

CTAs should feel like invitations, not instructions. Designer deals at your fingertips is stronger than Check out today's deals because it offers an immediate benefit and an emotional pull.

Specificity beats sentiment

Your goal is waiting is sentiment. You're 2 days into your streak is specificity.

Only one of those proves the product knows something real about the person receiving the message.

Rhetorical questions can also help because they prompt reflection, but use them sparingly. One per cadence is usually enough.

A practical structure

Title: [Friction point or context hook] (max 30-40 chars)
Body: [What's in it for them + next action] (max 60-90 chars)

Upwork’s approach is a strong model:

  • Title: Ask for that referral
  • Body: Not sure how to ask for referrals? Try these low-pressure approaches.

The title names a specific friction. The body resolves it.

Rewrite vague pushes into triggered ones

NotificationProblemBetter direction
Your goal is waiting.VagueYou're 2 days into [Goal Name]. Keep the streak.
Open the app and chat about anything.No real triggerSkip the send, or only trigger if the user has not opened in 3 days
Ready to make progress?GenericYou logged a 5K run yesterday! How did it feel?
Any questions for us?Brand-centricSomething on your mind? Jot it down before bed and clear your thoughts.

Frequency is product design

One push per day can hold roughly 88% three-month retention. Three per day can drop to 71%, and five to 54%. Separate studies also show most users quickly classify high-volume notifications as spam, and clickbait accelerates this fatigue.

In practice, a sensible ceiling is:

  • 2 per day maximum
  • 5 per week maximum
  • Behavioural triggers should take priority over scheduled sends

If a message is not urgent or immediately useful, do not send it.

Timing and personalisation

For many apps, 6pm-10pm is a high-visibility window. Outside that, send because something meaningful happened, not because a calendar slot fired.

Personalisation can increase reaction rates significantly, but true personalisation is not first-name insertion. It is tone, diction, recommendation quality, context, and recency awareness.

Duolingo’s system is a useful benchmark here: it selects reminder variants by user profile and includes a recency penalty, reducing the chance of sending again too soon to the same person.

The simpler version of that principle:

Every notification should only make sense for the person receiving it.
If it works for everyone, it is working for no one.

How permission gets lost

Using notifications as an advertising channel is the fastest path to opt-out. Once permission is gone, recovery is rare.

Patterns that accelerate loss:

  • Sending the same message twice in one stack
  • Sending without a real trigger
  • Making the brand the subject instead of the user
  • Using vague CTAs that hide what happens after the tap
  • Ignoring the user’s actual usage hours

Before every send, ask:

Would this feel like a friend texting me, or like a cron job firing?

If it is the cron job, do not send it.

Sources