Design a Notification Service
What is the Notification Service Problem?
Section titled “What is the Notification Service Problem?”Design a notification service that can send messages to users through multiple channels (email, SMS, push notifications). The service should support rate limiting to prevent overwhelming users, batching to optimize resource usage, template management for consistent messaging, user preferences for channel selection, and retry mechanisms for failed notifications. The system must be scalable, reliable, and easily extensible to support new notification channels in the future.
In this problem, you’ll design a robust orchestration engine that ensures reliable delivery at scale while respecting user boundaries and platform constraints.
Problem Overview
Section titled “Problem Overview”Design a universal notification platform that routes messages to users based on their preferences while maintaining high reliability and throughput.
Core Requirements
Section titled “Core Requirements”Functional Requirements:
- Multi-channel Support: Send via Email, SMS, and Push.
- Template Management: Support dynamic placeholders for consistent branding.
- User Preferences: Allow users to opt-in/out of specific channels.
- Rate Limiting: Prevent sending more than $X$ messages per hour per user.
- Retry Mechanism: Automatically retry failed sends with backoff.
- Batching: Group low-priority alerts into single digests.
Non-Functional Requirements:
- Scalability: Handle massive bursts of traffic.
- Extensibility: Easy to add new channels without refactoring.
- High Availability: Ensure URGENT notifications are prioritized.
- Fault Tolerance: Isolate failures so one downed provider doesn’t affect others.
What’s Expected?
Section titled “What’s Expected?”1. System Architecture
Section titled “1. System Architecture”The service acts as an orchestrator, coordinating between TemplateEngine, RateLimiter, and ChannelProviders.
2. Key Classes to Design
Section titled “2. Key Classes to Design”classDiagram
class NotificationService {
-TemplateManager templates
-RateLimiter limiter
-UserPreferences prefs
+send(userId, templateId, data)
}
class NotificationChannel {
<<interface>>
+send(message) bool
}
class EmailChannel {
+send(message)
}
class TemplateManager {
+render(id, variables) String
}
class RetryDecorator {
-NotificationChannel wrapped
+send(message)
}
NotificationService --> NotificationChannel
NotificationService --> TemplateManager
NotificationChannel <|-- EmailChannel
NotificationChannel <|-- SMSChannel
NotificationChannel <|-- PushChannel
System Flow
Section titled “System Flow”Notification Processing Flow
Section titled “Notification Processing Flow”Key Design Challenges
Section titled “Key Design Challenges”1. Decoupling Providers
Section titled “1. Decoupling Providers”If you hardcode SendGrid for emails, switching to Mailchimp later will be a nightmare.
Solution: Use the Strategy Pattern. The NotificationService interacts with a NotificationChannel interface. Concrete implementations (SendGridEmail, TwilioSMS) handle the provider-specific API logic.
2. Ensuring Delivery (Retries)
Section titled “2. Ensuring Delivery (Retries)”External APIs often fail due to transient network issues.
Solution: Use the Command Pattern with a Retry Decorator. Wrap the send command in a class that tracks attempt counts. If a send fails, the decorator uses an exponential backoff (wait 1s, then 2s, then 4s…) before retrying, ensuring you don’t overwhelm a recovering provider.
3. Batching vs. Real-time
Section titled “3. Batching vs. Real-time”A “Friend Liked Your Post” alert should be instant, but a “Weekly Summary” should be batched.
Solution: Implement Priority Queuing. Urgent messages bypass the queue and go straight to the provider. Low-priority messages are stored in a Buffer, and a background job (Task Scheduler) runs every hour/day to batch them into a single aggregate notification.
What You’ll Learn
Section titled “What You’ll Learn”By solving this problem, you’ll master:
- ✅ Strategy & Factory Patterns - Building a pluggable infrastructure.
- ✅ Template Methods - Standardizing complex multi-step workflows.
- ✅ Resiliency Patterns - Implementing retries, timeouts, and circuit breakers.
- ✅ Resource Optimization - Using rate limiting and batching to save costs and user sanity.
View Complete Solution & Practice
Section titled “View Complete Solution & Practice”Ready to see the full implementation? Open the interactive playground to access:
- 🎯 Step-by-step guidance through the 8-step LLD approach
- 📊 Interactive UML builder to visualize your design
- 💻 Complete Code Solutions in Python, Java, C++, TypeScript, JavaScript, C#
- 🤖 AI-powered review of your design and code
Related Problems
Section titled “Related Problems”After mastering the Notification Service, try these similar problems:
- Task Scheduler - Managing the backend queue for batched alerts.
- Chat Room Manager - Handling high-frequency real-time messaging.
- Rate Limiter - Deep dive into the mechanics of throughput control.