System Design FAQ: Top Questions
6. How would you design a Notification System (email, SMS, push)?
A Notification System delivers messages to users via various channels like email, SMS, push, or in-app alerts. It must be reliable, scalable, and capable of handling retries and failures.
๐ Functional Requirements
- Send alerts via multiple channels (email, SMS, push)
- Support templating and personalization
- Track delivery status and failures
- Provide retry logic and backoff strategies
๐ฆ Non-Functional Requirements
- High availability and low latency
- Message deduplication and idempotency
- Secure handling of user PII
๐๏ธ Architecture Overview
- Frontend/API Gateway: Triggers notification
- Notification Service: Core logic, templates, scheduling
- Channel Workers: Separate workers for Email, SMS, Push
- Queue: Kafka/SQS to decouple producers and consumers
- Audit Store: For delivery logs and analytics
๐ง Email Notification (Node.js + SendGrid)
const sgMail = require('@sendgrid/mail');
sgMail.setApiKey(process.env.SENDGRID_API_KEY);
const msg = {
to: 'user@example.com',
from: 'no-reply@myapp.com',
subject: 'Welcome!',
text: 'Thanks for signing up!',
html: 'Thanks for signing up!',
};
sgMail.send(msg).then(() => {
console.log('Email sent');
}).catch((error) => {
console.error(error);
});
๐ฑ SMS Notification (Python + Twilio)
from twilio.rest import Client
client = Client("ACXXXX", "your_auth_token")
message = client.messages.create(
body="Your OTP is 123456",
from_="+1234567890",
to="+19876543210"
)
print(message.sid)
๐ฒ Push Notification (Firebase FCM)
const admin = require('firebase-admin');
admin.initializeApp();
const payload = {
notification: {
title: "Reminder",
body: "You have a meeting at 10 AM"
}
};
admin.messaging().sendToDevice(deviceToken, payload)
.then(response => console.log("Push sent:", response))
.catch(err => console.error("Push error:", err));
๐งช Delivery Tracking Table (SQL)
CREATE TABLE notifications (
id UUID PRIMARY KEY,
user_id UUID,
channel VARCHAR(10), -- email, sms, push
status VARCHAR(20), -- pending, delivered, failed
created_at TIMESTAMP DEFAULT NOW(),
sent_at TIMESTAMP,
error TEXT
);
โฑ๏ธ Retry Strategy
- Exponential backoff with jitter
- Dead letter queue for unprocessed notifications
- Cap retries to avoid infinite loops
โ๏ธ Cloud Providers
- Email: AWS SES, SendGrid, Postmark
- SMS: Twilio, AWS SNS
- Push: Firebase Cloud Messaging (FCM), OneSignal
๐ง Scaling Considerations
- Batch processing for high throughput (Kafka consumers)
- Rate limits from 3rd-party APIs must be respected
- Use region-based workers for low latency
๐ Final Insight
A notification system is a cross-cutting concern in many systems. Abstracting delivery logic, using queues, and isolating channels help build resilient, testable infrastructure with observability.
