Skip to content

Notification Service System Design

Design a Notification Service that can send notifications through multiple channels:

  • Email
  • SMS
  • Push Notifications
  • In-app notifications

Example use cases:

  • Amazon order updates
  • OTP messages
  • Social media notifications
  • Payment alerts

The service should support millions of notifications per day.

  1. Send notifications via multiple channels.
  2. Support Email, SMS, Push, and In-app notifications.
  3. Support template-based notifications.
  4. Allow user notification preferences.
  5. Retry failed notifications.
  6. Support bulk notifications.
  7. Provide notification history.
  • High scalability
  • Low latency
  • Fault tolerance
  • Reliable delivery
  • Retry support
  • Idempotency
flowchart TD
    A["Client Services<br/>Order Service<br/>Payment Service"] --> B[Notification API]
    B --> C[Notification Service]
    C --> D[Kafka Queue]
    C --> E[Template Service]
    C --> F[User Preference Service]
    D --> G[Notification Workers]
    G --> H[Email Service]
    G --> I[SMS Service]
    G --> J[Push Service]
    H --> K[SendGrid]
    I --> L[Twilio]
    J --> M[Firebase]

Entry point responsible for:

  • Receiving notification requests
  • Validating requests
  • Publishing events to the queue
POST /notifications

Examples:

  • Kafka
  • RabbitMQ
  • AWS SQS

Purpose:

  • Asynchronous processing
  • Decouple producers and consumers
  • Handle traffic spikes

Responsibilities:

  • Fetch user preferences
  • Fetch templates
  • Render message
  • Send notifications
  • Retry on failure

Stores reusable templates.

Example:

Hi {name}, your order {orderId} has been shipped

Users configure enabled channels.

UserPreference
--------------
userId
emailEnabled
smsEnabled
pushEnabled

Separate integrations for each delivery channel.

  • Email -> SendGrid / SES
  • SMS -> Twilio
  • Push -> Firebase
Notification
------------
id
user_id
type
channel
status
payload
created_at
sent_at
retry_count
Template
--------
template_id
channel
template_name
template_body
language
created_at
UserPreference
--------------
user_id
email_enabled
sms_enabled
push_enabled
updated_at
class NotificationRequest {
String userId;
NotificationType type;
Channel channel;
Map<String, String> data;
}
interface NotificationService {
void sendNotification(NotificationRequest request);
}

Implementation:

class NotificationServiceImpl implements NotificationService {
QueuePublisher queuePublisher;
public void sendNotification(NotificationRequest request) {
queuePublisher.publish(request);
}
}
class NotificationWorker {
TemplateService templateService;
ChannelFactory channelFactory;
public void process(NotificationRequest request) {
Template template =
templateService.getTemplate(request.type);
String message = TemplateEngine.render(
template,
request.data
);
Channel channel =
channelFactory.getChannel(request.channel);
channel.send(message);
}
}
interface Channel {
void send(String message);
}
class EmailChannel implements Channel {
EmailProvider provider;
public void send(String message) {
provider.sendEmail(message);
}
}
class SMSChannel implements Channel {
SMSProvider provider;
public void send(String message) {
provider.sendSMS(message);
}
}
class ChannelFactory {
public Channel getChannel(ChannelType type) {
switch(type) {
case EMAIL:
return new EmailChannel();
case SMS:
return new SMSChannel();
case PUSH:
return new PushChannel();
}
}
}

Pattern used: Factory Pattern

POST /notifications

Request:

{
"userId": "123",
"type": "ORDER_SHIPPED",
"channel": "EMAIL",
"data": {
"name": "John",
"orderId": "A123"
}
}
GET /notifications/{userId}

Use exponential backoff.

1st retry -> 1 min
2nd retry -> 5 min
3rd retry -> 15 min

Retry topic:

notification_retry

Use a unique notification ID.

if (notificationAlreadySent)
skip;
  • Horizontally scale workers.
  • Partition Kafka topics.
  • Use worker pools.
  • Batch large campaigns (e.g., 10M notifications).

Dead Letter Queue:

notification_dlq

Used after maximum retries are exhausted.

Monitor:

  • Notifications per second
  • Failure rate
  • Retry count
  • Provider latency

Tools:

  • Prometheus
  • Grafana
  • ELK
  • Amazon SNS
  • Firebase Cloud Messaging
  • Uber Notification Platform
  • LinkedIn Kafka-based notification systems
  1. Prevent notification spam.
  2. Handle 10M push notifications in one minute.
  3. Prioritize OTP notifications over marketing notifications.
  4. Ensure exactly-once delivery.
  5. Support multi-language notifications.
  • Asynchronous processing with queues enables scalability and resilience.
  • Separate workers and channel integrations isolate provider-specific logic.
  • Templates and user preferences improve flexibility and personalization.
  • Retries, DLQs, and idempotency improve reliability.
  • Horizontal scaling and partitioned queues support very high throughput.