Design a Notification Service
Intermediate · 22 min read · Low-Level Design, Case Studies: Advanced
Channels, templates, preferences, quiet hours, priority, dedup, failover and dead letters.
"Design a notification service" is asked as LLD at most product companies because every one of them has built one. The object design is simple — request, channels, templates — but the interviewer listens for the policies: user preferences, quiet hours, rate limits, deduplication, priority (an OTP must not wait behind…
What the interviewer expects
The full design in this lesson is longer than anything you'd write in one round. It's there so you understand the edge cases and can answer follow-up questions. In the round itself, aim for this:
1. Requirements
2. Design
Two important modelling choices:
3. Accepting requests: idempotency first
Set.add on a concurrent set is atomic, so two threads submitting the same key can't both enqueue. In production the seen-keys set needs a TTL (a day is typical) or it grows forever.
4. Priority: an OTP never waits behind marketing
The queue is a PriorityBlockingQueue ordered by category, then arrival:
5. Processing a delivery: the policy pipeline
Points worth saying out loud:
6. Channels and providers: Adapter + failover chain
Each vendor SDK (SES, Twilio, FCM) gets an adapter implementing one small Provider interface. A channel tries its providers in order:
7. Concurrency
The reference solution submits 2,000 requests from 8 threads (every idempotency key twice) to 4 workers and checks exactly 1,000 unique deliveries.
8. Patterns used
9. Extensions
Interview questions
- How do you make sure a user doesn't receive the same notification twice?
- A marketing campaign enqueues 5 million messages. How do OTPs still go out in seconds?
- What happens when the SMS provider is down?
Further reading
Key takeaways
- One request fans out into one delivery per channel, each with its own status and retries.
- Enforce idempotency at intake; order work by priority so critical messages never wait behind bulk traffic.
- Apply policies in order — preferences, quiet hours (defer), rate limits — and record every outcome with a reason.
- Adapters per vendor with a failover chain; transient failures retry with backoff, permanent ones fail fast; dead-letter what can't be delivered.
Previous: Design a Job Scheduler · Next: Design a Cab Booking System