Notification System Design - Complete Low-Level Design Guide
Design a scalable Notification System using Java and Spring Boot. Learn requirement analysis, UML class diagrams, multi-channel notifications, templates, retries, scheduling, user preferences, SOLID principles, design patterns, and enterprise architecture.
Introduction
Every modern application sends notifications.
Examples include:
- Banking transaction alerts
- OTP verification
- Password reset emails
- Order confirmations
- Shipping updates
- Insurance claim notifications
- Appointment reminders
- Marketing campaigns
- Security alerts
- Promotional offers
Large platforms such as:
- Amazon
- Netflix
- PayPal
- Uber
send millions of notifications every hour.
A Notification System must deliver messages reliably through multiple communication channels while handling failures, retries, scheduling, and user preferences.
In this guide, we'll design a production-ready Notification System using Java and Spring Boot.
Problem Statement
Design a Notification System that supports:
- Email Notifications
- SMS Notifications
- Push Notifications
- In-App Notifications
- WhatsApp Notifications
- Scheduled Notifications
- Retry Mechanisms
- Templates
- User Preferences
- Delivery Tracking
Functional Requirements
The system should support:
- Send Notification
- Schedule Notification
- Retry Failed Notifications
- Cancel Scheduled Notifications
- Notification Templates
- Delivery Status Tracking
- User Preferences
- Multi-channel Delivery
- Bulk Notifications
- Priority Notifications
Non-Functional Requirements
The system should be:
- Highly Available
- Scalable
- Fault Tolerant
- Secure
- Extensible
- Maintainable
- Event Driven
Actors
Actors include:
- User
- Application
- Notification Service
- Email Provider
- SMS Provider
- Push Provider
- Administrator
High-Level Architecture
flowchart TD
CLIENT["Application"]
NOTIF["Notification Service"]
TEMPLATE["Template Engine"]
PREF["User Preference Service"]
BROKER["Message Queue / Event Bus"]
EMAIL["Email Channel"]
SMS["SMS Channel"]
PUSH["Push Channel"]
WHATSAPP["WhatsApp Channel"]
PROVIDER["External Delivery Providers"]
CLIENT --> NOTIF
NOTIF --> TEMPLATE
NOTIF --> PREF
NOTIF --> BROKER
BROKER --> EMAIL
BROKER --> SMS
BROKER --> PUSH
BROKER --> WHATSAPP
EMAIL --> PROVIDER
SMS --> PROVIDER
PUSH --> PROVIDER
WHATSAPP --> PROVIDER
Core Components
The system consists of:
- Notification
- Notification Request
- Template
- Channel
- User
- Preference
- Delivery Service
- Retry Service
- Scheduler
- Queue
Domain Model
classDiagram
class Notification
class User
class Template
class Channel
class Preference
class Scheduler
class Delivery
class Retry
User --> Preference
Notification --> Template
Notification --> Channel
Notification --> Delivery
Delivery --> Retry
Entity Responsibilities
Notification
Stores:
- Notification ID
- Type
- Priority
- Status
- Channel
- Content
User
Stores:
- User ID
- Name
- Phone
- Device Token
Template
Stores:
- Template Name
- Subject
- Body
- Variables
Preference
Stores:
- Preferred Channels
- Language
- Quiet Hours
- Opt-In Settings
Delivery
Stores:
- Delivery Status
- Provider
- Timestamp
Retry
Stores:
- Retry Count
- Retry Time
- Failure Reason
Notification Types
OTP
Transaction
Promotion
Reminder
Alert
Marketing
Password Reset
Security
Notification Channels
Email
SMS
Push Notification
WhatsApp
In-App
Webhook
Notification Lifecycle
flowchart LR
Created
-->
Queued
-->
Sending
-->
Delivered
Sending --> Failed
Failed --> Retry
Retry --> Delivered
Notification Workflow
sequenceDiagram
participant App
participant NotificationService
participant Queue
participant EmailService
App->>NotificationService: Send Notification
NotificationService->>Queue: Publish
Queue->>EmailService: Consume
EmailService-->>App: Delivered
Multi-Channel Delivery
flowchart TD
Notification
-->
Email
Notification --> SMS
Notification --> Push
Notification --> WhatsApp
Notification --> InApp
One notification can be delivered through multiple channels based on user preferences.
Template Engine
Instead of hardcoding messages:
Hello {{name}}
Your OTP is {{otp}}
Expires in {{minutes}} minutes.
Templates improve consistency and localization.
User Preferences
Users may configure:
- Email only
- SMS only
- Push only
- Multiple channels
- Quiet hours
- Language
The system should honor these preferences before sending notifications.
Notification Priority
Critical
High
Medium
Low
Critical alerts bypass promotional throttling and quiet hours where appropriate.
Scheduling
flowchart LR
CLIENT["Create Notification Request"]
SCHEDULER["Scheduling Service"]
QUEUE["Message Queue / Event Bus"]
DELIVERY["Delivery Engine"]
CLIENT --> SCHEDULER --> QUEUE --> DELIVERY
Examples:
- Appointment reminders
- Birthday wishes
- Subscription renewals
- Payment reminders
Retry Mechanism
Temporary failures should be retried.
flowchart LR
REQUEST["Request Processing"]
FAILURE["Failure Detected"]
RETRY["Retry Engine"]
SUCCESS["Successful Delivery"]
DEAD["Dead Letter Queue"]
REQUEST --> FAILURE --> RETRY --> SUCCESS
RETRY --> DEAD
Common strategy:
- Retry 3 times
- Exponential Backoff
- Move to DLQ after max retries
Dead Letter Queue
flowchart LR
Queue
-->
Delivery
Delivery --> Failed
Failed --> DLQ
Failed notifications are stored for manual investigation.
Bulk Notifications
Example:
Promotion
↓
1 Million Users
↓
Queue
↓
Multiple Workers
Workers process notifications independently for high throughput.
Design Patterns
Factory Pattern
Create notification channels:
- SMS
- Push
- Webhook
Strategy Pattern
Channel-specific sending logic.
Each provider implements its own strategy.
Observer Pattern
Business events trigger notifications automatically.
Examples:
- Order Placed
- Payment Completed
- Password Changed
Template Method Pattern
Common notification flow:
- Validate
- Build Message
- Send
- Update Status
Different channels customize the sending step.
Singleton
Notification Configuration
SOLID Principles
SRP
EmailService only sends emails.
SMSService only sends SMS.
TemplateService only renders templates.
OCP
Support new channels without modifying existing services.
LSP
Every notification channel behaves like a NotificationChannel.
ISP
Separate interfaces:
- Sender
- Scheduler
- Retry
DIP
NotificationService depends on channel abstractions.
Concurrency
Challenges:
- Duplicate delivery
- Message ordering
- Race conditions
- Retry collisions
Solutions:
- Message Queues
- Idempotency Keys
- Optimistic Locking
- Distributed Workers
Database Design
User
Notification
Template
Preference
Delivery
Retry
NotificationLog
Spring Boot Layers
flowchart LR
Controller
-->
Service
-->
Repository
-->
PostgreSQL
REST APIs
POST /notifications
POST /notifications/bulk
POST /notifications/schedule
POST /notifications/cancel
GET /notifications/{id}
GET /users/{id}/preferences
PUT /users/{id}/preferences
Enterprise Architecture
flowchart TD
CLIENT["Application"]
GATEWAY["API Gateway"]
SERVICE["Notification Service"]
TEMPLATE["Template Engine"]
PREF["User Preference Service"]
BUS["Kafka Event Bus"]
WORKERS["Channel Workers"]
EMAIL["Email Worker"]
SMS["SMS Worker"]
PUSH["Push Worker"]
WA["WhatsApp Worker"]
CACHE["Redis Cache"]
DB["PostgreSQL Database"]
OBS["Monitoring & Observability"]
CLIENT --> GATEWAY --> SERVICE
SERVICE --> TEMPLATE
SERVICE --> PREF
SERVICE --> BUS
BUS --> EMAIL
BUS --> SMS
BUS --> PUSH
BUS --> WA
SERVICE --> CACHE
SERVICE --> DB
SERVICE --> OBS
Redis:
- Rate limiting
- Idempotency
- Temporary cache
Kafka:
- NotificationCreated
- NotificationSent
- DeliveryFailed
- RetryScheduled
Scaling Considerations
Large enterprises may send:
- Millions of Emails
- Millions of SMS
- Millions of Push Notifications
Scaling techniques:
- Kafka
- RabbitMQ
- Amazon SQS
- Horizontal Workers
- Redis
- Rate Limiting
- Batch Processing
- Provider Failover
Future Enhancements
Possible features:
- AI-generated messages
- Smart channel selection
- Multi-language templates
- Delivery analytics
- Read receipts
- Click tracking
- A/B testing
- Notification digest
- User segmentation
- Provider failover routing
Common Mistakes
❌ Hardcoding message content.
❌ No retry strategy.
❌ Ignoring user preferences.
❌ No template engine.
❌ Tight coupling with providers.
❌ No DLQ.
❌ No idempotency.
Interview Questions
- How would you support multiple notification channels?
- How would you implement retries?
- Why should notifications use queues?
- Which design patterns are useful?
- How would you support scheduling?
- How would you implement user preferences?
- How would you prevent duplicate notifications?
- How would you scale to millions of messages?
- How would you support provider failover?
- How would you monitor delivery success?
Summary
A Notification System is a foundational enterprise service that enables reliable communication across multiple channels.
A production-ready implementation should include:
- Rich domain models
- Layered Spring Boot architecture
- SOLID principles
- Factory, Strategy, Observer, Template Method, and Singleton patterns
- Queue-based asynchronous processing
- Retry and Dead Letter Queue support
- Template engine
- User preferences
- REST APIs
- Redis for caching and rate limiting
- Kafka for event-driven delivery
- Monitoring and delivery analytics
Mastering this design prepares you for advanced systems such as Email Platforms, Marketing Automation, Event-Driven Microservices, Customer Engagement Platforms, Banking Alert Systems, and Enterprise Messaging Services, where scalability, reliability, and extensibility are essential.