Push Notifications That People Do Not Mute
Most apps lose notification permission in the first ninety seconds, and everything you send afterward depends on what happened in those ninety seconds.
A pizza shop we know sent one push at 4:58pm on a Friday: "Your order is ready — window 2." Open rate, 71%. Three weeks later the same shop sent "🍕 FRIDAY VIBES! 20% off ALL pies!!" to the same list at 11:40am. Open rate, 3.1%. Notification permission revocations that week: 9% of the install base. Same audience, same app, same delivery pipe. The only variable was whether the message was about something the customer had already started.
That gap is the whole subject. Notification permission is not a marketing channel you acquired — it is a small amount of trust that you spend down every time you send, and top up only when the message turns out to have been worth the interruption.
The first-launch permission prompt is the most expensive mistake in the build
On iOS, UNUserNotificationCenter.requestAuthorization can be called exactly once in a way that matters. If the user taps "Don't Allow," the system will never show that dialog again. Your only remaining move is deep-linking them into Settings, which almost nobody does. On Android 13 and above the POST_NOTIFICATIONS runtime permission behaves similarly — two dismissals and it's permanently denied for that install.
So the timing of that single prompt determines the ceiling on everything you will ever do with notifications for that user. Firing it in initState on the first screen is the equivalent of asking someone for their phone number before you've said hello.
The numbers people report, roughly, across consumer apps:
- Cold prompt on first launch: commonly 30–45% accept on iOS. Android runs higher, often 50–65%, because users are less trained to refuse it.
- Prompt after a completed action (first booking, first order, first saved item): commonly 55–75% on iOS.
- Prompt with a plain-language pre-permission screen explaining exactly what you'll send, with a "Not now" that actually works: 65–80% is achievable, and importantly the "Not now" group can be asked again in two weeks because you never burned the system dialog.
The pre-permission pattern is the single highest-leverage thing in this article. You show your own screen first. If they tap your "Not now," no system dialog is fired, no permanent denial is recorded, and you can re-ask after the next meaningful action. Only when they tap your "Yes" do you call the system API — at which point acceptance is close to certain.
For a booking app, the natural moment is right after the first appointment is confirmed, with copy like: "Want a reminder the morning of, and a heads-up if your stylist has to move the time?" That's not a marketing ask. That's an offer to be useful, and it lands very differently.
Transactional and marketing are two different products that happen to share a delivery pipe
The distinction matters more than most teams treat it. A transactional push is about a thing the user already initiated: an order status, an appointment moving, a message from a real human, a payment failing. A marketing push is about a thing you want them to start: a promotion, a re-engagement nudge, a feature announcement.
| Transactional | Marketing | |
|---|---|---|
| Typical open rate | 25–55% | 1.5–5% |
| Effect on opt-out | Near zero, sometimes negative | Primary driver of revocation |
| Sensible time-of-day | Whenever the event happens | Narrow windows only |
| Sensible ceiling | Uncapped — it's event-driven | 1–4 per month |
The practical consequence is that they need separate toggles and separate channels. On Android, use distinct NotificationChannels — "Order updates," "Appointment reminders," "Offers and news" — so a user who is annoyed by promos can mute exactly that channel from the system UI instead of muting your app entirely. That is a strictly better outcome for you: you keep the pipe for the messages that actually convert.
Android gives you this granularity for free at the OS level. iOS doesn't, so you build it in your own settings screen and honor it server-side. Either way, the mistake to avoid is a single "Notifications: On/Off" switch, because when someone reaches for it they're annoyed about promos and they will take your order updates down with them.
Provisional authorization on iOS, and where it earns its keep
iOS offers .provisional in the authorization options. Request it and you get permission immediately, with no dialog at all. The catch: those notifications are delivered quietly to Notification Center — no banner, no sound, no badge on the lock screen. Each one carries "Keep" and "Turn Off" buttons, and tapping Keep promotes you to full delivery.
This is genuinely useful in one specific situation: you have something worth sending but no earned moment yet to ask for permission. A retail catalog app where the user browses for three sessions before buying anything is a good candidate. You send two or three quiet, genuinely relevant notifications, and the ones who find them useful promote you themselves.
It's a bad fit when the first message is time-critical — a quiet notification in Notification Center is not a reliable way to tell someone their table is ready. And your reported opt-in metric will look inflated, because provisional counts as authorized. Track the promotion rate separately; in practice a reasonable target is 20–35% of provisional users promoting to full within their first month, and if you're under 10% your content is the problem, not the mechanism.
Frequency ceilings, and the segments that make them survivable
Marketing frequency is where most small business apps quietly destroy their list. The pattern is predictable: launch, send weekly promos because the dashboard makes it easy, watch open rates fall from 8% to 2% over eleven weeks, and never notice that permission revocations climbed the whole time because nobody put that number on a chart.
Reasonable ceilings, by category:
- Restaurants and food: 2–4 marketing pushes per month, and almost all of the value sits in the 30–90 minute window before a normal meal decision — 11:00–11:30am and 4:30–5:30pm.
- Salons, clinics, trades: 1–2 per month. The reminder cadence is the real product; promos are a garnish.
- Fitness and classes: up to weekly, but only to people who attended in the last 21 days. To lapsed members it's an eviction notice.
- Retail: 4 per month is defensible if genuinely segmented; 8 is not, regardless of segmentation.
Segmentation is the mechanism that makes any of these tolerable. Three segments get you most of the value: people who transacted in the last 30 days, people who transacted 31–120 days ago, and people who have never transacted. The last group should receive almost nothing — they installed and didn't buy, and a discount push is unlikely to change that while a mute is very likely.
What actually drives the uninstall
Uninstalls rarely trace to a single notification. They trace to a pattern the user has decided about, usually inside the first fourteen days.
The reliable triggers, in rough order of damage: notifications outside 9am–8pm local time (and "local" means the user's timezone, which requires storing it — a surprising number of apps send on server time and wake people at 3am); messages with no personal referent, where nothing in the text connects to anything the user did; identical copy repeated across sends; and the promo that arrives immediately after a support complaint went unanswered.
Two instruments worth building before launch. First, a per-user send log with a hard cap enforced server-side — not in the campaign tool, in the sending code — so no dashboard mistake can send four pushes in an hour. Second, a chart of weekly permission revocations sitting next to open rate. Open rate falling is ambiguous. Revocations rising is not, and it's the number that tells you the channel is being spent faster than it's being earned.
White-label Flutter apps, delivered in 30-60 days, from $2,500 - full source code included.
Get started