Chaturmind
LearnDSASystem DesignDevOpsEngineering GrowthBlog
Start learning
Chaturmind

Structured learning paths for engineers who want to go deep. Written by practitioners.

Learn

  • Java
  • DSA
  • System Design
  • Spring Boot
  • AI / ML
  • DevOps
  • Engineering Growth

Company

  • Blog
  • Contact

Legal

  • Privacy Policy
  • Terms of Service

Β© 2026 Chaturmind. All rights reserved.

Built for engineers who want to go deep.


← System Design Interview Playbook

Interview Framework

  • The 6-Step Design Framework
  • HLD Fundamentals Refresher
  • Requirement Gathering Practice
  • Domain Decomposition
  • API Contract Design
  • Data Ownership Model
  • Failure Scenario Walkthroughs
  • Architecture Diagramming
  • Back-of-Envelope Estimation

10 Case Studies

  • Design a URL Shortener
  • Design Twitter / X
  • Design WhatsApp
  • Design Netflix
  • Design a Rate Limiter
  • Design a Search Autocomplete
  • Design a Distributed Cache
  • Design a Notification Service
  • Design Uber / Ride Sharing
  • Design a Distributed File Storage System
  • Design a Distributed Task Scheduler
  • Design a Message Queue System
  • Design an Authentication System at Scale
  • Design a Distributed Logging & Metrics Pipeline
  • Design a Food Delivery Platform
  • Design a Real-Time Analytics Dashboard
  • Design a Monitoring & Alerting System
  • Design Container Orchestration Basics
  • Design a CI/CD Pipeline System
  • Design Service Mesh Basics
  • Design a Centralized Configuration & Secrets System
  • Design a Batch Processing System
  • Design a Data Warehouse / Analytics Storage Layer
  • Design Global Content Delivery
  • Case studies

    πŸ—οΈDesign a URL Shortener
  • πŸ—οΈDesign a Rate Limiter
  • πŸ—οΈDesign Twitter / X
  • πŸ—οΈDesign WhatsApp
  • πŸ—οΈDesign Netflix
  • πŸ—οΈDesign a Distributed Cache
  • πŸ—οΈDesign a Notification Service
  • πŸ—οΈDesign a Search Autocomplete System
  • πŸ—οΈDesign Uber / Ride Sharing
  • πŸ—οΈDesign a Web Crawler
  • πŸ—οΈDesign a Payment System
  • πŸ—οΈDesign a Distributed Lock Service
  • πŸ—οΈDesign a Video Streaming Platform
  • πŸ—οΈDesign a Search Engine
  • πŸ—οΈDesign E-Commerce Checkout & Inventory at Scale
Chaturmind
← System Design Interview Playbook

Interview Framework

  • The 6-Step Design Framework
  • HLD Fundamentals Refresher
  • Requirement Gathering Practice
  • Domain Decomposition
  • API Contract Design
  • Data Ownership Model
  • Failure Scenario Walkthroughs
  • Architecture Diagramming
  • Back-of-Envelope Estimation

10 Case Studies

  • Design a URL Shortener
  • Design Twitter / X
  • Design WhatsApp
  • Design Netflix
  • Design a Rate Limiter
  • Design a Search Autocomplete
  • Design a Distributed Cache
  • Design a Notification Service
  • Design Uber / Ride Sharing
  • Design a Distributed File Storage System
  • Design a Distributed Task Scheduler
  • Design a Message Queue System
  • Design an Authentication System at Scale
  • Design a Distributed Logging & Metrics Pipeline
  • Design a Food Delivery Platform
  • Design a Real-Time Analytics Dashboard
  • Design a Monitoring & Alerting System
  • Design Container Orchestration Basics
  • Design a CI/CD Pipeline System
  • Design Service Mesh Basics
  • Design a Centralized Configuration & Secrets System
  • Design a Batch Processing System
  • Design a Data Warehouse / Analytics Storage Layer
  • Design Global Content Delivery
  • Case studies

    πŸ—οΈDesign a URL Shortener
  • πŸ—οΈDesign a Rate Limiter
  • πŸ—οΈDesign Twitter / X
  • πŸ—οΈDesign WhatsApp
  • πŸ—οΈDesign Netflix
  • πŸ—οΈDesign a Distributed Cache
  • πŸ—οΈDesign a Notification Service
  • πŸ—οΈDesign a Search Autocomplete System
  • πŸ—οΈDesign Uber / Ride Sharing
  • πŸ—οΈDesign a Web Crawler
  • πŸ—οΈDesign a Payment System
  • πŸ—οΈDesign a Distributed Lock Service
  • πŸ—οΈDesign a Video Streaming Platform
  • πŸ—οΈDesign a Search Engine
  • πŸ—οΈDesign E-Commerce Checkout & Inventory at Scale
HomeLearnSystem DesignSystem Design Interview Playbook10 Case Studies
βœ“ FreeIntermediateΒ· 6 min read

Design a Notification Service

How to run the notification-service design in a 45-minute interview: requirements to clarify, the queue-based architecture, dedup and priority deep dives, and the follow-ups to expect.

Published September 21, 2026


Design a Notification Service β€” the 45-minute interview walkthrough

This lesson is the interview version of the design: what to say, in what order, and which decisions to defend, so you can deliver it within a normal HLD interview. The full reference design, with capacity numbers, API and data model in detail, is the case study Design a Notification Service in this same chapter.

A notification service is the one place every other service calls when it needs to tell a user something ("your order shipped", "your OTP is 481233", "Asha liked your post"). It decides whether to send (user preferences, rate limits), how (push, email, SMS), when (now, or batched), and makes sure the message arrives once, even though every provider in the chain can fail.

Minutes 0–5: clarify requirements

Ask before drawing anything. The answers change the design:

  • Channels? Push (iOS APNs, Android FCM), email, SMS. In-app inbox too?
  • Volume and spikes? Assume ~10M notifications/day (~115/s average), with spikes of 50–100Γ— when a marketing campaign or a breaking event fans out to millions.
  • Latency by type? An OTP or security alert must arrive in seconds. "Order shipped" within a minute is fine. Marketing can take hours.
  • Guarantees? "At least once, deduplicated" is the realistic target. Exactly-once across external providers isn't achievable.
  • User control? Per-channel and per-type opt-out, quiet hours, and legal unsubscribe for marketing email.

State the priorities you'll optimize for: no lost critical notifications, no duplicates the user notices, and marketing volume must never delay OTPs.

Minutes 5–15: the high-level design

 Order / Payment / Social services
          β”‚  POST /notifications  { userId, type, data, idempotencyKey, priority }
          β–Ό
 β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   validates, applies preferences + rate limits,
 β”‚  Notification API  β”‚   renders the template, stores a record
 β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
           β”‚ publish by priority
   β”Œβ”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
   β–Ό       β–Ό                β–Ό
 [critical] [transactional] [bulk]        ← separate queues/topics per priority
   β”‚          β”‚                β”‚
   β–Ό          β–Ό                β–Ό
 Channel workers: push-worker β”‚ email-worker β”‚ sms-worker
           β”‚
           β–Ό
 APNs / FCM Β· SES / SendGrid Β· Twilio      ← external providers (can fail, can rate-limit you)
           β”‚
           β–Ό
 Delivery status + provider callbacks β†’ status store β†’ analytics

Walk the interviewer through one request end to end: the caller sends an event with an idempotency key. The API checks preferences, renders the text, saves a record as PENDING, and enqueues it on the right priority queue. A channel worker picks it up, calls the provider, and records SENT or schedules a retry.

Why a queue in the middle? It absorbs spikes (a campaign of 5 million emails becomes a backlog, not an outage). It decouples callers from slow providers (the Order service's request returns immediately). And it lets each channel scale its workers independently.

Minutes 15–35: the deep dives interviewers pick

1. Duplicates and retries

Duplicates come from two places: producers retrying (the Order service didn't get a response and calls again) and workers retrying (the provider timed out but may actually have sent). The answer has two layers:

  • An idempotency key per logical notification, supplied by the caller (for example order-123:shipped). The API stores it with a unique constraint, so a repeated request returns the existing record instead of creating another.
  • The worker marks the send before acknowledging the queue message, and on retry checks the stored status first.

Admit the limit: if a provider accepts a message and then times out, you can't know whether it was delivered. You retry, and occasionally the user gets two. The job is to make that rare and harmless, not impossible.

2. Priority isolation

If OTPs and a 5-million-email campaign share one queue, the OTP waits behind the campaign. Separate queues (or topics) per priority, with their own worker pools, guarantee critical traffic a fast lane. Bulk sends are also throttled deliberately so they don't hit provider rate limits and get your whole account throttled, OTPs included.

3. Provider failures

Every external provider will have outages and rate limits:

  • Retries with exponential backoff and jitter, up to a limit, then a dead-letter queue for inspection.
  • A circuit breaker per provider, so a failing provider is skipped quickly instead of tying up workers.
  • A secondary provider for critical channels (a second SMS vendor for OTPs), switched to automatically when the breaker opens.

4. Preferences and rate limiting

Preferences are read on every send, so they live in a fast store (a cache in front of the database). Add per-user rate limits ("no more than 3 marketing pushes a day") and quiet hours. Transactional and security messages usually bypass quiet hours; marketing never does.

Minutes 35–45: trade-offs and wrap-up

Summarize the choices and what you'd do next:

  • At-least-once + idempotency instead of chasing exactly-once.
  • Priority queues protect critical messages at the cost of more infrastructure.
  • Templates rendered in the service (not by each caller) keep branding and localization consistent, but make the service a shared dependency, so it must be highly available.
  • Next steps with more time: per-provider delivery analytics (callback webhooks), digesting (turn 20 "someone liked your post" pushes into one), multi-region delivery.

Common mistakes in interviews

  • Calling providers synchronously from the API request, which makes every caller as slow and fragile as the slowest provider.
  • One queue for everything, so a marketing blast delays password resets.
  • Claiming exactly-once delivery, which interviewers will immediately probe.
  • Forgetting user preferences and unsubscribe, which are legal requirements for marketing email in many countries.

Follow-up questions this topic invites β€” and their answers

Q: How do you send one campaign to 50 million users without melting anything? A: Don't create 50 million requests up front. A campaign job pages through the audience in chunks and enqueues them onto the bulk queue at a controlled rate that stays under provider limits. Workers scale on queue depth. The campaign takes an hour, which is fine for marketing, and critical queues stay untouched.

Q: Push or pull for the in-app notification inbox? A: Store inbox items per user (newest first, capped), and deliver in real time over an existing WebSocket or long-poll connection when the user is online. When they're offline, the item waits in the inbox and a push notification brings them back. The inbox is the source of truth, and pushes are just nudges.

Q: How do you know a notification was actually delivered? A: Providers report asynchronously: email bounces and opens, SMS delivery receipts, APNs/FCM feedback about invalid tokens. Expose webhook endpoints for these callbacks and update the status record. Remove invalid device tokens so you stop paying to send to dead devices.

Q: How would you support multiple regions? A: Run the pipeline in each region, route users to their home region, and keep preferences replicated. Pay attention to data residency (some countries require user data to stay in-region) and to provider choice per region: SMS vendors differ in coverage and cost by country.

Previous

Design a Distributed Cache

Next

Design Uber / Ride Sharing

AI Tutor

Lesson: Design a Notification Service

Quick actions

AI responses can be inaccurate. Verify critical information.