Notifications: email, push and in-app, without annoying users
Notifications are the feature users turn off first. How to design them so people keep them on and act on them.
The short answer
Notifications are the feature users turn off first, because most are sent for the sender’s convenience rather than the recipient’s need. A notification earns its interruption in one of two ways: it requires an action, or it prevents a problem. Everything else, activity, status, someone did something, belongs in a digest or in the application for the user to see when they choose. Three channels do three jobs. Push interrupts, so it is for the time-critical few. Email persists and is searchable, so it is for things to act on and keep. In-app is for everything else. Give users control per type, sensible defaults, batching and quiet hours, and they keep notifications on and act on them.
Three channels, three jobs
| Channel | Character | Use it for | Do not use it for |
|---|---|---|---|
| Push | Interrupts now, short, easily dismissed | Time-critical: a booking in an hour, a payment failed, a message waiting for a reply | Activity, marketing, anything that can wait an hour |
| Persists, searchable, can carry detail | Things to act on and keep: approvals, documents, summaries, security events | Every event as it happens | |
| In-app | Seen when the user chooses; can be rich | Activity feeds, status changes, mentions, what changed since last visit | Things that need action before the user’s next visit |
| Digest | Batched at a chosen time | Everything that is interesting but not urgent | Anything urgent |
Designing the set
- List every event the system could notify about.
- Sort each into: needs action now, needs action soon, prevents a problem, or nice to know.
- Assign channels: push for now, email for soon and for records, in-app or digest for the rest.
- Set defaults to what a thoughtful user would choose; essentials on, activity off or digested.
- Give per-type controls with plain descriptions, plus quiet hours and a digest schedule.
- Batch bursts: ten comments in a minute is one notification.
- Write each message as what happened, what to do, where, with a direct link.
- Measure opt-outs per type and remove or demote the types people switch off.
Writing the message
What happened, in the first line, specifically: “Invoice 2026-0412 was rejected by the client” rather than “You have a new update”. What to do: “Review the reason and resend”. Where: a link that opens the exact record, already logged in where the platform allows. Who it is from, when it is relevant. Nothing else. A notification that can be understood and acted on from its first line is one that people keep.
What this means for you
Design notifications as interruptions that must be earned: action or prevention gets a push or an email, everything else goes in-app or into a digest. Give users per-type control, sensible defaults, batching and quiet hours. Write every message as what happened, what to do and where. Users who trust that a notification means something keep them on, and that trust is the whole value of the feature.
Frequently asked questions
How many notifications are too many?
One more than the user would have chosen to receive. The number varies by role; the principle does not: interrupt only for things that need action now or would cause harm if missed, batch the rest, and let each user tune the types. Watch the opt-out rate per type; a type people turn off was not earning its interruption.
Push, email or in-app?
Push for the time-critical few, because it interrupts. Email for things the user must act on and may want to find later, because it persists and is searchable. In-app for status, activity and anything the user can catch up on when they open the application. Most notifications belong in the last category and are sent through the first by mistake.
Should notifications be on by default?
The essential ones, yes: things about the user's own work that need action. Activity and marketing types, off by default or in a digest. Defaults are what most users keep, so the default set is the product decision; make it the set a thoughtful user would choose.