Bird
0
0
LLDsystem_design~7 mins

Notification system in LLD - System Design Guide

Choose your learning style9 modes available
Problem Statement
When users perform actions or when system events occur, failing to inform users promptly leads to poor user experience and missed opportunities for engagement. Without a structured notification system, messages can be delayed, lost, or sent in an inconsistent manner, causing confusion and dissatisfaction.
Solution
A notification system centralizes the creation, management, and delivery of messages to users through various channels like email, SMS, or push notifications. It queues notifications, applies user preferences, and retries failed deliveries to ensure timely and reliable communication.
Architecture
Event Source
(User Action)
Notification
Notification
Queue/Store

This diagram shows how events trigger notifications that are queued and processed by delivery handlers respecting user preferences.

Trade-offs
✓ Pros
Ensures reliable delivery by queuing and retrying failed notifications.
Supports multiple channels (email, SMS, push) through modular handlers.
Respects user preferences to avoid spamming and improve engagement.
Decouples event generation from notification delivery for scalability.
✗ Cons
Adds complexity with the need to manage queues and delivery status.
Requires handling of failures and retries which can increase latency.
Needs storage for queued notifications and user preferences.
Use when your system needs to notify thousands or more users asynchronously with multiple delivery channels and user-specific preferences.
Avoid if your application only requires simple, synchronous alerts for a small user base under 100 users.
Real World Examples
Uber
Uber uses a notification system to inform riders and drivers about trip status updates, cancellations, and promotions reliably across SMS and app push notifications.
Airbnb
Airbnb sends booking confirmations, reminders, and review requests through email and push notifications, managing user preferences and delivery retries.
LinkedIn
LinkedIn delivers notifications about connection requests, messages, and job alerts through multiple channels, ensuring timely and personalized delivery.
Code Example
Before, notifications were sent directly inside business logic, mixing concerns and risking delays or failures. After applying the notification system pattern, notifications are queued and sent asynchronously respecting user preferences, improving reliability and scalability.
LLD
### Before: No notification system, direct calls
class OrderService:
    def place_order(self, user, order):
        # process order
        self.send_email(user.email, "Order placed")

    def send_email(self, email, message):
        # direct email sending
        print(f"Sending email to {email}: {message}")


### After: Using Notification System
from enum import Enum

class Channel(Enum):
    EMAIL = 'email'
    SMS = 'sms'

class Notification:
    def __init__(self, user_id, message, channel):
        self.user_id = user_id
        self.message = message
        self.channel = channel

class NotificationQueue:
    def __init__(self):
        self.queue = []

    def enqueue(self, notification):
        self.queue.append(notification)

    def dequeue(self):
        if self.queue:
            return self.queue.pop(0)
        return None

class NotificationService:
    def __init__(self, queue, user_prefs):
        self.queue = queue
        self.user_prefs = user_prefs

    def notify(self, user_id, message):
        prefs = self.user_prefs.get(user_id, [Channel.EMAIL])
        for channel in prefs:
            notification = Notification(user_id, message, channel)
            self.queue.enqueue(notification)

    def process_notifications(self):
        notification = self.queue.dequeue()
        while notification:
            self.send(notification)
            notification = self.queue.dequeue()

    def send(self, notification):
        print(f"Sending {notification.channel.value} to user {notification.user_id}: {notification.message}")


class OrderService:
    def __init__(self, notification_service):
        self.notification_service = notification_service

    def place_order(self, user_id, order):
        # process order
        self.notification_service.notify(user_id, "Your order has been placed.")


# Usage
user_prefs = {1: [Channel.EMAIL, Channel.SMS], 2: [Channel.EMAIL]}
queue = NotificationQueue()
notif_service = NotificationService(queue, user_prefs)
order_service = OrderService(notif_service)

order_service.place_order(1, "Order123")
notif_service.process_notifications()
OutputSuccess
Alternatives
Polling-based notification
Clients periodically request updates instead of receiving push notifications.
Use when: Choose when real-time delivery is not critical and system simplicity is preferred.
Webhook-based notification
External systems receive notifications via HTTP callbacks rather than internal delivery.
Use when: Choose when integrating with third-party services that require event callbacks.
Summary
A notification system ensures reliable, timely delivery of messages to users across multiple channels.
It decouples event generation from message delivery using queues and respects user preferences.
This pattern improves user engagement and system scalability by handling retries and failures gracefully.