Skip to main content
System DesignInterview Prep

Design a Notification System: System Design Interview Walkthrough

How to design a scalable notification system for push, SMS and email: architecture, queues per channel, retries and idempotency, user preferences, rate limiting and delivery tracking.

InterviewPilot TeamOctober 17, 20263 min read

Notification systems look easy until you ask what happens at a million messages a minute with flaky providers. See also the system design cheat sheet.

1. Requirements

Functional: send push, SMS, email (and in-app); templates; user preferences; scheduling; delivery status. Non-functional: high throughput, reliable delivery, low latency for critical messages, no duplicates, easy to add channels.

2. Architecture

Services -> Notification API -> Validator/Preferences -> Template Renderer
                                           |
                             Priority queues (per channel)
                         /          |             \
                    Push worker  SMS worker   Email worker
                        |            |             |
                      FCM/APNs   SMS provider   Email provider
                                           |
                                   Delivery log / analytics

3. Key design decisions

Queues per channel and priority

A slow email provider mustn't delay OTP SMS messages. Separate queues and worker pools per channel, and a high-priority lane for transactional messages.

Reliability: at-least-once + idempotency

Queues deliver at least once, so a worker may process a message twice. An idempotency key (notification ID) stored with a short TTL lets workers skip duplicates.

Retries

Retry with exponential backoff and jitter; after N attempts move to a dead-letter queue for inspection.

Provider failover

Keep a secondary provider for SMS/email and switch when error rates cross a threshold.

Preferences and compliance

Check opt-outs, channel preferences and quiet hours before enqueueing. Email unsubscribe and SMS stop requests must be honored.

Rate limiting

Limit per user (avoid spamming), per provider (respect quotas). See designing a rate limiter.

Templates and localization

Store templates with variables and locales; render at the worker or a template service.

4. Data model

  • notifications(id, userId, type, channel, payload, status, createdAt)
  • preferences(userId, channel, category, enabled, quietHours)
  • device_tokens(userId, platform, token)

5. Delivery tracking

Record states: queued, sent, delivered, failed, opened (where the provider reports it). Provider callbacks (webhooks) update status asynchronously.

6. Follow-ups

  • Scheduled and recurring notifications (delayed queue or scheduler)
  • Batching or digests to reduce noise
  • Invalid push tokens: remove after provider feedback
  • Multi-region delivery and data residency

Sizing

Say the product sends 100 million notifications per day: about 1,200 per second on average, perhaps 10x that during a campaign. Email and SMS providers rate limit and charge per message, so queues and throttling matter as much as raw throughput.

Template and personalization

Store templates with named variables and locale variants. A render step fills the variables and picks the right language. Keep rendering stateless so you can scale workers horizontally, and version templates so you can audit what a user actually received.

Handling third-party providers

ConcernApproach
Rate limitsToken bucket per provider, smoothing sends
OutagesCircuit breaker and failover to a secondary provider
WebhooksDelivery and bounce callbacks update status; verify signatures
CostRoute transactional messages to premium routes, marketing to cheaper ones
Invalid tokensRemove device tokens when the provider reports them dead

Scheduling and batching

  • Scheduled notifications: a delayed queue or scheduler that enqueues at the due time
  • Digests: collect events over a window and send one summary
  • Quiet hours: hold non-urgent messages until the user's local morning

Observability

Track enqueue-to-send latency, success and failure rate per channel and provider, queue depth, retry counts and dead-letter volume. Alert on queue depth growth and rising failure rates, which are early signs of a provider problem.

Security and compliance

  • Never put secrets or full personal data in push payloads
  • Honour unsubscribe and do-not-disturb requests immediately
  • Keep an audit trail of consent
  • For OTPs, expire quickly and rate limit sends (rate limiter design)

Interview tips

Start by listing the channels and priorities, because a design that treats an OTP like a newsletter is a common mistake. Close with failure handling: what happens when a provider is down at peak.

Frequently asked questions

Was this article useful?

Discussion

No comments yet. Been through an interview like this? Your experience could help the next candidate.

You’re posting anonymously — it appears after a quick review. Sign in to post under your name instantly.
0/2000

Bring backup into your next round.

Install InterviewPilot, upload your resume, and walk in with structured answers a keystroke away — visible to you and nobody else.