Design push and background work for a chat application delivering to hundreds of millions of devices.
Show the full answer Hide the answer
The delivery reality
Push is best-effort: not guaranteed, not ordered, potentially delayed, and subject to platform throttling that increases as a user interacts less with the app. Payload size is small.
So push is a hint to fetch, not a carrier of state. A design that treats a notification as the delivery mechanism for content will lose messages and display stale ones.
The fanout problem
A message to a large channel means a notification per subscribed device, and the naive implementation generates that fanout synchronously on the message path — coupling message delivery latency to notification volume.
- Separate the paths. Message delivery to connected clients is real-time; notification fanout is asynchronous and may lag without affecting chat.
- Suppress notifications for connected clients, since a user with the app open does not need one and this removes a large share of the volume.
- Aggregate rather than send per message. A busy channel must produce a summary, not fifty notifications — this is both a user experience requirement and the main volume control.
- Respect per-user and per-channel preferences at fanout time, not on the device, so undeliverable notifications are never generated.
Token and background handling
- Token lifecycle management: tokens rotate, expire and become invalid, and a system that does not prune them wastes a growing share of its fanout on dead devices.
- Background fetch is limited and unreliable on both platforms — treat it as an optimisation, never as a correctness mechanism.
- Coalesce background work, since radio wake-ups dominate battery cost and several small syncs cost far more than one combined one.
The failure mode to design against
A backlog burst on reconnection. A device offline for hours reconnects and the server sends everything at once. Rate-limit the drain, prefer a summary over a replay, and let the client fetch history on demand rather than pushing it.