How to Design a Notification System in a System Design Interview
A notification system design guide covering preferences, fan-out, queues, provider failures, idempotency, retries, and delivery analytics.
Separate intent from delivery
A notification system starts when another product service emits an intent: send this user a password reset, order update, comment mention, or marketing campaign. The notification service should decide channel, template, preferences, rate limits, and delivery provider.
This separation keeps product services from hard-coding email, SMS, push, retries, and provider-specific behavior.
Model preferences and idempotency early
Preferences are not a UI detail. They decide whether a notification should be sent at all. The service needs user-level and notification-type preferences, unsubscribe state, quiet hours, localization, and legal constraints for marketing messages.
Idempotency matters because upstream services retry. A stable notification key prevents duplicate password resets, duplicate receipts, or repeated alerts during incident retries.
Use queues for channel fan-out
Email, SMS, push, and in-app delivery have different latency, cost, retry, and provider behavior. Put channel-specific work behind queues so each worker pool can scale independently and absorb provider slowness.
- Transactional notifications should have higher priority than bulk marketing.
- Retries need backoff and a dead-letter queue.
- Provider failover needs dedupe so fallback does not double-send.
- Delivery events should feed analytics without blocking sends.
Make delivery observable
Strong answers include metrics: accepted events, filtered events, send attempts, provider latency, bounce rate, retry rate, dead-letter count, and user-visible delivery delay. Without those signals, the system can silently stop notifying users.