Back to System Design
System Design
Notification system
Senior level · full staged walkthrough
Senior
Architecture
SeniorClientAsyncServiceDataEdge
Solution, step by step
- 1
Functional requirements
- Multi-channel: push, email, SMS, in-app
- Templating + localization
- User preferences & opt-out
- Delivery tracking
- 2
Non-functional requirements
- At-least-once delivery + idempotency
- Throttling/dedup per user
- Provider failover
- Burst tolerance
- 3
Capacity & estimation
- Peak campaigns: 100M notifications in minutes → 100K+/s
- Per-channel provider rate limits → buffering required
- Status records: billions/month → partitioned store
- Retry queue depth grows during provider outages
- 4
Preliminary design
- Producers enqueue events
- Channel workers render templates and call providers
- Idempotency keys + retry with backoff
- 5
Final architecture
- Event queue (Kafka) decouples producers from delivery
- Dispatcher applies user preferences, dedup, and throttling
- Per-channel worker pools with provider adapters + rate limiting
- Idempotency keys + retry with exponential backoff and DLQ
- Status store + webhooks reconcile delivery/read state
Interview Q&A (8)
At-least-once with idempotency keys: enqueue durably, retry with exponential backoff, and dedupe on the key so retries don't double-send.
Key components
- Event queue
- Template service
- Channel workers
- Provider adapters
- Status store
Bottlenecks & how to address them
- Provider rate limits → token-bucket per provider
- Retry storms → backoff + DLQ
- Template rendering cost → cache compiled templates
Tradeoffs to articulate
- At-least-once + idempotency vs exactly-once
- Per-user throttling vs immediacy
- Provider failover complexity
Where this content comes from
For full transparency, this content is curated and verified from these sources:
Published architecture case studiesCompany engineering blogsOppZen design rubric library