Design a Notification System
Practice a notification-system design with user preferences, multi-channel delivery, retries, provider failures, deduplication, and delivery observability.
What you'll learn
Run the architecture drill
- How to separate notification intent, policy evaluation, and channel delivery.
- How to retry without sending duplicates or violating user preference changes.
- How to reason about provider outages and multi-channel fallback in an interview.
A notification system turns product events into timely messages while respecting user preferences and unreliable external delivery providers. The design is not about sending an email or push notification once. It is about policy, fanout, idempotency, delivery state, retry behavior, and knowing what "delivered" means for each channel.
Start with the architecture drill, then follow the request path through scale, failure, and a defensible interview answer.
Make your assumptions and decision path easy to inspect.
ATOFF architecture reasoning canvas
Design a Notification System: the architecture drill
Short answer
A notification system turns product events into policy-aware, deduplicated channel deliveries while accepting that external providers cannot offer a single universal success state.
10× evolution
Partition delivery work by tenant and channel while protecting provider quotas.
01 Decision checkpoint
Design brief
Resolve recipient, consent, preference, priority, and channel eligibility before creating delivery work, not inside every provider adapter.
02 Decision checkpoint
First request path
Assign a stable notification and channel attempt identity so retries, webhook callbacks, and provider timeouts cannot produce accidental duplicate messages.
03 Decision checkpoint
Failure drill
Use adapters and durable delivery state to absorb provider-specific errors, throttles, receipts, and failover without leaking them into product events.
Say it in the interview
I would separate preference resolution, durable delivery intent, and provider execution, then define what each channel means by accepted versus delivered.
- 1
Product event
create intent: Notification intent
- 2
Notification intent
recipient set: Idempotent delivery fanout
- 3
Preferences + policy
consent + channel: Idempotent delivery fanout
- 4
Idempotent delivery fanout
email task: Email worker + provider · push or SMS task: Push / SMS worker + provider
- 5
Email worker + provider
callback: Delivery state + retry policy
- 6
Push / SMS worker + provider
callback: Delivery state + retry policy
- 7
Delivery state + retry policy
bounded retry: Idempotent delivery fanout
- Product event flows to Notification intent via create intent.
- Notification intent flows to Idempotent delivery fanout via recipient set.
- Preferences + policy flows to Idempotent delivery fanout via consent + channel.
- Idempotent delivery fanout flows to Email worker + provider via email task.
- Idempotent delivery fanout flows to Push / SMS worker + provider via push or SMS task.
- Email worker + provider flows to Delivery state + retry policy via callback.
- Push / SMS worker + provider flows to Delivery state + retry policy via callback.
- Delivery state + retry policy flows to Idempotent delivery fanout via bounded retry.
Walk the design under pressure
Define the notification contract before choosing channels
Clarify whether the system sends transactional, marketing, security, or operational messages; whether recipients can opt out by channel; and whether a message must be ordered with other messages in the same conversation. A security alert has different delivery and audit requirements from a weekly product digest.
Model an immutable notification intent separately from an attempted delivery. That lets the system show why a user did or did not receive something while allowing retries, provider changes, and preference updates to be handled transparently.
Fanout needs stable delivery identities
One event may notify many recipients through multiple channels. Generate a stable idempotency key from the notification intent, recipient, channel, and version. Workers can then retry safely and provider callbacks can be reconciled without interpreting every duplicate as a new message.
Preferences must be evaluated at a clearly defined point. A simple design checks them when tasks are created; a more sensitive system rechecks before send so a recent opt-out is honored. Explain the consistency tradeoff rather than assuming policy data is instantly global.
Treat external providers as slow, fallible dependencies
Email, SMS, and push providers can throttle, time out, accept a request but delay a callback, or fail regionally. Use timeouts, bounded retry schedules with jitter, channel-specific failure categories, and a dead-letter process with an owner. Do not blindly fail over from a low-priority email to an expensive SMS without a product rule.
Provider acceptance is not the same as device delivery or user read. Store the strongest status the channel can actually prove and make the UI language match that evidence.
Staff-level insight: delivery is a policy and trust system
At staff scope, delivery rate, provider concentration, preference correctness, and message fatigue are all product risks. Build auditability for changes to templates and preferences, protection against notification storms, and dashboards that distinguish backlog, provider rejection, and user suppression.
In an interview, close by describing evolution: start with one channel and durable queue, then add templates, preference versioning, provider routing, and regional isolation when evidence justifies it.
Keep this with you
Key takeaways
- A notification intent and a channel delivery attempt are different records with different lifecycles.
- Idempotency, policy timing, and provider status semantics prevent duplicate or unwanted messages.
- Retry strategy must reflect channel cost, user trust, and what the provider can prove.
Practice aloud
Interview questions to explore
- 1.How do you avoid sending the same message twice after a timeout?
- 2.When are preferences evaluated, and what happens if they change during a retry?
- 3.What does delivery mean for email, push, and SMS in your design?
Common follow-ups
Frequently asked questions
Should all notifications use one queue?
Not necessarily. Separate queues or policies can protect urgent security messages from high-volume marketing work and allow distinct retry, provider, and rate-limit behavior.
Can a system guarantee a user reads a notification?
No. It can usually observe provider acceptance or device receipt depending on the channel, but reading is a user action and should be modeled separately when available.
Already an Elite member? Open the complete walkthrough.
Need the broader preparation context? Go back to Interview Preparation for behavioral readiness, question practice, and the larger AceTheOffer preparation framework.