Real-time notification delivery system
Web sockets, message broker, and delivery handlers in action.
Delivering a notification is more complex than it looks: a user action triggers an event, that event enters a queue, the delivery system checks preferences and rules, and only then does it reach a push provider — with retries, fallbacks, and audit trails at each step. This template maps the full journey from event publication through device receipt.
The sequence diagram format makes the asynchronous nature clear: your app fires the event and moves on; the broker and delivery service work independently, decoupled from the user's request. If a provider is slow or temporarily down, the queue buffers the load, and retries happen invisibly.
When to use this template
- Designing notification infrastructure — agree on queuing strategy, provider selection, and retry logic before you build. This diagram is the architecture in a single image.
- Debugging delivery failures — each step is a failure point. Trace which box in the diagram is silent, and you've found the bug (queue not consuming, preferences broken, provider rate-limited, etc.).
- Onboarding the on-call team — when a notification storm hits or a provider outage happens, this diagram is the decision tree for triage.
How to adapt it
Customize the providers and the routing logic to your stack:
- Add multiple providers in parallel — if you have both Firebase and AWS SNS, add both as participants and let the delivery service try both, or pick by device type.
- Insert a retry loop — after "provider rejects", add a loop back with exponential backoff (e.g., wait 5s, try again; wait 30s, try again; after 3 tries, dead-letter).
- Add channel selection — between preferences and send, add a decision (user language? phone SMS or email? quiet hours?). Each decision branch picks a different provider.
Because visual edits regenerate code, you can drag new participants onto the sequence, add decision boxes, and move messages around — the result is always valid Mermaid.
Mermaid code
Copy it anywhere Mermaid is supported — GitHub, Notion, or your docs.
sequenceDiagram
actor User
participant App
participant Queue as Message Broker
participant Delivery as Delivery Service
participant Provider as Push Provider
User->>App: Trigger notification event
App->>Queue: Publish notification message
Queue->>Delivery: Consume message
Delivery->>Delivery: Check user preferences
alt User enabled notifications
Delivery->>Provider: Send push notification
Provider->>Provider: Queue for delivery
Provider-->>Delivery: Accepted
Provider-->>User: Deliver to device
User->>Provider: Device receives push
else User disabled
Delivery->>Delivery: Log as suppressed
end
Delivery->>Queue: Acknowledge message
Frequently asked questions
- Why use a message broker for notifications?
- A message broker decouples the event producer (your app) from the delivery system. If the delivery service is temporarily down, messages queue safely instead of bouncing back to your app. It also enables retries, dead-letter handling, and distribution to multiple delivery handlers without blocking the user's request.
- What is the difference between a provider and a delivery service?
- The delivery service is your internal orchestrator — it reads the message queue, applies user preferences and rules, and decides which channels (SMS, email, push) to use. The provider is the external service (Apple, Google, Firebase, Twilio) that actually sends the notification to the user's device. The delivery service abstracts away provider differences.
- What happens if a notification fails to deliver?
- The broker can retry the message (exponential backoff is standard), and the delivery service logs the failure and the reason (device offline, provider rate-limited, user unsubscribed). After N retries, the message goes to a dead-letter queue for manual review. Some systems also attempt alternate channels — if push fails, try email.
- How do I adapt this for SMS or email notifications?
- The flow is identical: your app publishes to the queue, the delivery service consumes and applies routing logic, and it sends through the chosen provider. To support multiple channels, add a routing decision after preferences (e.g., if SMS failed or is unavailable, retry with email). Visual edits regenerate clean Mermaid code, so you can expand the diagram with your own provider branches.