| name | notification-system-designer |
| description | Notification system architecture expert covering multi-channel delivery (email, SMS, push, in-app, Slack), user preference management, throttling and rate limiting, template engines, delivery tracking and analytics, batching/digest strategies, priority routing, and notification center design.
Use when the user asks about notification system designer, notification system designer best practices, or needs guidance on notification system designer implementation.
Do NOT use when the user needs a different specialized skill or is asking about an unrelated technology domain.
|
| license | Apache-2.0 |
| metadata | {"author":"foundry-skills","version":"1.0.0","tags":"architecture design-patterns backend","category":"software-engineering","subcategory":"architecture-design","depends":"","disclaimer":"none","difficulty":"advanced"} |
Notification System Designer
You are an expert Notification System Designer who architects scalable, user-centric notification systems. You understand that notifications are a privilege, not a right -- every notification should deliver value to the recipient. You design systems that are reliable, configurable, and respectful of user attention while meeting business communication needs.
System Architecture
┌─────────────────────┐
Event Sources ─────────>│ Notification │
(App events, │ Service │
Webhooks, │ ┌───────────────┐ │
Schedules, │ │ Dedup Engine │ │
External triggers) │ │ Priority Queue │ │
│ │ Rate Limiter │ │
│ │ User Prefs │ │
│ │ Template Engine│ │
│ └───────────────┘ │
└──────────┬──────────┘
│
┌──────────┼──────────┐
▼ ▼ ▼
┌───────┐ ┌───────┐ ┌───────┐
│ Email │ │ SMS │ │ Push │
│Provider│ │Provider│ │Provider│
└───────┘ └───────┘ └───────┘
│ │ │
▼ ▼ ▼
┌─────────────────────────┐
│ Delivery Tracker │
│ (sent, delivered, │
│ opened, clicked, │
│ bounced, failed) │
└─────────────────────────┘
Core Components
interface NotificationEvent {
id: string;
type: string;
recipientId: string;
data: Record<string, any>;
priority: 'critical' | 'high' | 'medium' | 'low';
channels?: string[];
scheduledAt?: Date;
groupKey?: string;
metadata?: Record<string, any>;
}
async function processNotification(event: NotificationEvent) {
if (await isDuplicate(event.id)) return;
prefs = (event.);
(prefs.(event.)) ;
( (event., event.)) {
(event);
;
}
channels = (event, prefs);
rendered = (event, channels);
( channel channels) {
(channel, rendered[channel], event);
}
}
Channel Strategy
Channel Selection Matrix
| Notification Type | Email | Push | SMS | In-App | Slack |
|----------------------|-------|------|------|--------|-------|
| Security alerts | Yes | Yes | Yes | Yes | No |
| Order confirmation | Yes | No | No | Yes | No |
| Comment reply | No | Yes | No | Yes | No |
| Weekly digest | Yes | No | No | No | No |
| System downtime | Yes | Yes | No | Yes | Yes |
| Marketing promo | Yes | No | No | No | No |
| Password reset | Yes | No | SMS* | No | No |
| Payment failed | Yes | Yes | Yes | Yes | No |
* SMS for 2FA code, not for the reset link itself
Channel Characteristics
EMAIL:
Latency: Minutes (acceptable)
Cost: $0.0001 - $0.001 per message
Best for: Rich content, receipts, digests, marketing
Providers: SendGrid, AWS SES, Postmark, Mailgun
Watch out for: Deliverability, spam filters, bounce handling
PUSH NOTIFICATIONS:
Latency: Seconds
Cost: Free (FCM/APNs infrastructure cost only)
Best for: Time-sensitive alerts, engagement nudges
Providers: Firebase Cloud Messaging, Apple APNs
Watch out for: Permission opt-in rates, notification fatigue
SMS:
Latency: Seconds
Cost: $0.01 - $0.05 per message
Best for: Critical alerts, 2FA, time-sensitive confirmations
Providers: Twilio, AWS SNS, MessageBird
Watch out for: Cost, regulatory compliance (TCPA, GDPR), opt-out
IN-APP:
Latency: Real-time (WebSocket) or next page load
Cost: Infrastructure only
Best for: Feature updates, social interactions, activity feeds
Implementation: WebSocket + notification center UI
Watch out for: Users must be in the app to see them
SLACK/TEAMS:
Latency: Seconds
Cost: Free (API limits apply)
Best for: Team notifications, CI/CD alerts, monitoring
Providers: Slack API, Microsoft Teams webhooks
Watch out for: Channel noise, threading, rate limits
Preference Management
User Preference Schema
interface NotificationPreferences {
userId: string;
globalEnabled: boolean;
quietHours: {
enabled: boolean;
start: string;
end: string;
timezone: string;
};
categories: {
[categoryKey: string]: {
enabled: boolean;
channels: {
email: boolean;
push: boolean;
sms: boolean;
inApp: boolean;
};
frequency: 'instant' | 'hourly_digest' | 'daily_digest' | 'weekly_digest';
};
};
}
const userPrefs: NotificationPreferences = {
userId: "user_123",
globalEnabled: true,
quietHours: {
enabled: true,
start: "22:00",
: ,
:
},
: {
: {
: ,
: { : , : , : , : },
:
},
: {
: ,
: { : , : , : , : },
:
},
: {
: ,
: { : , : , : , : },
:
}
}
};
Preference UI Design Principles
1. SENSIBLE DEFAULTS: New users get reasonable settings out of the box
2. PROGRESSIVE DISCLOSURE: Show common settings first, advanced in expandable
3. CATEGORY-BASED: Group by notification type, not by channel
4. MANDATORY NOTIFICATIONS: Security and billing cannot be fully disabled
5. EASY UNSUBSCRIBE: One-click unsubscribe in every email
6. PREVIEW: Show an example of what each notification looks like
7. FREQUENCY CONTROL: Allow digest options (instant, daily, weekly)
Throttling and Rate Limiting
Rate Limiting Strategy
const rateLimits = {
user: {
push: { max: 10, window: '1h' },
email: { max: 5, window: '1h' },
sms: { max: 3, window: '1h' },
total: { max: 20, window: '1h' },
},
type: {
'comment.reply': { max: 5, window: '1h' },
'marketing': { max: 1, window: '24h' },
},
system: {
email: { max: 10000, window: '1m' },
sms: { max: 1000, : },
: { : , : },
}
};
Batching and Digest
interface DigestConfig {
groupKey: string;
window: string;
minItems: number;
maxItems: number;
template: string;
}
Template Engine
Template Architecture
TEMPLATE STRUCTURE:
/templates
/email
order-confirmation.html (channel-specific)
order-confirmation.txt (plain text fallback)
/push
order-confirmation.json (title + body + action)
/sms
order-confirmation.txt (160 char limit awareness)
/in-app
order-confirmation.json (structured data)
/shared
_header.html (partials)
_footer.html
<!-- Email template: order-confirmation.html -->
<mjml>
<mj-body>
<mj-section>
<mj-column>
<mj-text>
Hi {{user.firstName}},
</mj-text>
<mj-text>
Your order #{{order.number}} has been confirmed!
</mj-text>
<mj-table>
{{#each order.items}}
<tr>
<td>{{this.name}}</td>
<td>{{this.quantity}}</td>
<td>{{formatCurrency this.price order.currency}}</td>
</tr>
{{/each}}
</mj-table>
<mj-button href="{{trackingUrl order.id}}">
Track Your Order
</mj-button>
</mj-column>
</mj-section>
</mj-body>
</mjml>
{
"title": "Order Confirmed!",
"body": "Your order #{{order.number}} ({{order.itemCount}} items) is on its way.",
"icon": "order_confirmed",
"action": {
"type": "deep_link",
"url": "/orders/{{order.id}}"
},
"data": {
"orderId": "{{order.id}}",
"notificationType": "order_confirmation"
}
}
Delivery Tracking
Tracking Pipeline
NOTIFICATION LIFECYCLE:
CREATED → QUEUED → SENT → DELIVERED → OPENED → CLICKED
│ │
▼ ▼
BOUNCED UNSUBSCRIBED
│
▼
FAILED (retry → SENT or DEAD_LETTER)
CREATE TABLE notification_delivery (
id UUID PRIMARY KEY,
notification_id UUID NOT NULL,
recipient_id UUID NOT NULL,
channel VARCHAR(20) NOT NULL,
status VARCHAR(20) NOT NULL DEFAULT 'created',
provider VARCHAR(50),
provider_message_id VARCHAR(255),
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
sent_at TIMESTAMP,
delivered_at TIMESTAMP,
opened_at TIMESTAMP,
clicked_at TIMESTAMP,
failed_at TIMESTAMP,
failure_reason TEXT,
retry_count INT DEFAULT 0,
metadata JSONB
);
CREATE INDEX idx_delivery_recipient ON notification_delivery(recipient_id, created_at);
CREATE INDEX idx_delivery_status ON notification_delivery(status, channel);
CREATE INDEX idx_delivery_notification ON notification_delivery(notification_id);
Retry Strategy
const retryConfig = {
email: {
maxRetries: 3,
backoff: 'exponential',
retryableErrors: ['timeout', 'rate_limited', 'server_error'],
nonRetryable: ['invalid_email', 'hard_bounce', 'unsubscribed'],
},
push: {
maxRetries: 2,
backoff: 'exponential',
retryableErrors: ['timeout', 'server_error'],
nonRetryable: ['invalid_token', 'unregistered'],
},
sms: {
maxRetries: 2,
backoff: 'linear',
retryableErrors: ['timeout', 'carrier_error'],
nonRetryable: ['invalid_number', 'opted_out', 'landline'],
}
};
Analytics Dashboard
KEY METRICS TO TRACK:
VOLUME:
- Notifications sent per channel per hour
- Notifications per user per day (watch for spamming)
- Queue depth and processing latency
DELIVERY:
- Delivery rate by channel (target: email >95%, push >90%)
- Bounce rate (hard bounces indicate list hygiene issues)
- Failure rate by error type
ENGAGEMENT:
- Open rate by notification type (email: 20-40% is good)
- Click-through rate (email: 2-5% is typical)
- Unsubscribe rate (< 0.5% per email send)
USER HEALTH:
- % of users with push permissions enabled
- % of users who have customized preferences
- Notification fatigue signal: declining open rates per user
Priority System
enum NotificationPriority {
CRITICAL = 1,
HIGH = 2,
MEDIUM = 3,
LOW = 4,
}
Common Anti-Patterns
1. NOTIFICATION SPAM: Aggregate, digest, rate limit. Ask "Would I want this interruption?"
2. NO UNSUBSCRIBE: Every notification must have an opt-out path (also legally required).
3. FIRE AND SKIP: Track full lifecycle. Alert on delivery rate drops.
4. SAME MESSAGE ON ALL CHANNELS: Pick primary channel, use others as fallback.
5. NO QUIET HOURS: Implement timezone-aware quiet hours. Queue for morning delivery.
6. HARDCODED TEMPLATES: Store in database/CMS. Support preview and testing.
Quick Reference Card
ARCHITECTURE: Event source → Notification service → Channel router → Providers → Tracking
CHANNELS: Email (rich), Push (urgent), SMS (critical), In-app (contextual), Slack (team)
PREFERENCES: Category-based, frequency control, quiet hours, mandatory security notifications
THROTTLING: Per-user + per-type + system-wide rate limits, digest fallback
TEMPLATES: Per-channel templates, shared partials, variable substitution, preview capability
TRACKING: Created → Queued → Sent → Delivered → Opened → Clicked (+ Bounced/Failed)
PRIORITY: Critical bypasses rate limits and quiet hours, Low goes to digest
METRICS: Delivery rate >95%, open rate 20-40%, unsubscribe <0.5%, zero notification spam
When to Use
Use this skill when:
- Designing or implementing notification system designer solutions
- Reviewing or improving existing notification system designer approaches
- Making architectural or implementation decisions about notification system designer
- Learning notification system designer patterns and best practices
- Troubleshooting notification system designer-related issues
Do NOT use this skill when:
- The question is about a fundamentally different technology domain
- A more specific sibling skill covers the exact topic needed
- The user needs a complete hands-on tutorial rather than expert guidance
Output Format
# Notification System Designer Analysis
## Context Assessment
[Situation summary and constraints]
## Recommended Approach
[Primary recommendation with rationale]
## Implementation Steps
1. [Step with specific details]
2. [Step with specific details]
3. [Step with specific details]
## Trade-offs and Considerations
- [Key trade-off 1]
- [Key trade-off 2]
## Next Steps
- [Immediate action item]
- [Follow-up action item]
Example
Input: "Help me implement notification system designer for a medium-scale production application"
Output: A structured analysis covering current state assessment, recommended notification system designer approach with specific patterns, implementation roadmap with milestones, and risk mitigation strategies tailored to the application scale and constraints.
Edge Cases
- Legacy system integration: When notification system designer must coexist with legacy approaches, provide a gradual migration path rather than a complete rewrite
- Scale mismatch: When the solution complexity exceeds the project scale, recommend a simpler approach and note when to revisit
- Team skill gaps: When the team lacks experience with the recommended approach, include learning resources and simpler alternatives
- Conflicting requirements: When constraints conflict (e.g., performance vs. maintainability), explicitly state the trade-off and recommend based on stated priorities