LLD7 min read
Notification Service
Multi-channel notifications (email/SMS/push) with template, retry and rate-limit decorators.
llddesign
Intro
A notification service must dispatch the right message to the right channel for the right user, with templating, localisation, opt-outs and retries. The clean model: Channel implementations behind a unified interface; pipeline of decorators around the send.
Functional
- Send templated messages to user via Email, SMS or Push.
- Respect user channel preferences and opt-outs.
- Retry with exponential backoff on transient failures.
- Throttle per-user to prevent floods.
Non-functional
- Asynchronous send (fire and forget).
- Idempotent — duplicate dispatch must not double-send.
Components
Notification
Templated message + recipient + variables.
Channel
Interface: EmailChannel (SES), SmsChannel (Twilio), PushChannel (FCM).
TemplateEngine
Renders body with localised strings + variables.
Dispatcher
Picks channel(s) per user preference; submits to queue.
RetryPolicy / RateLimiter / DeduplicationStore
Decorators around Channel.send.
Code
Snippetjava
interface Channel { void send(Message m); }
class RetryingChannel implements Channel {
private final Channel delegate;
private final RetryPolicy policy;
public void send(Message m) {
for (int attempt = 0; attempt < policy.maxAttempts(); attempt++) {
try { delegate.send(m); return; }
catch (TransientFailure e) { sleep(policy.backoff(attempt)); }
}
throw new GiveUpException();
}
}
class IdempotentChannel implements Channel {
private final Channel delegate;
private final Set<String> seen;
public synchronized void send(Message m) {
if (!seen.add(m.idempotencyKey)) return;
delegate.send(m);
}
}Pitfalls
- Embedding retry / rate-limit logic inside each Channel — duplicates code.
- Forgetting an idempotency key — webhooks / queues will replay messages.