Notification System Design — Architecture Decision Records
The purpose of this article is to analyze and digest the notification system and practice the ADR. It’s just a practice, not for the real…
Notification System Design — Architecture Decision Records

Introduction
The purpose of this article is to analyze and digest the notification system and practice the ADR. It’s just a practice, not for the real case.
In this article, we will list challenges and focus on the key decisions.
Agenda
- Understanding Requirements (defining scope)
- Challenges, Estimating Scale, and Bottleneck
- System Design Overview
- Technical Stack & Infra
- Workflow
- Architecture Decision Records
Understanding Requirements (defining scope)
Functional requirements
- Accept events from multiple upstream sources (e.g.,
order service,auth service) - Trigger one or more notifications per events
- Support for
delivery channels - Store and enforce user preferences for
notification typesandchannels Template-basedmessage generation withlocalization support- Implement
retry logicanddead-letter handlingfor failed messages - Expose APIs for
sending custom notificationsandmanaging preferences
Non-functional requirements
- Low
latency - notification should be near real-time
< few seconds Scalability- handle
millionof notifications/day,burst trafficatpeak Reliability- guarantee
at least oncedelivery Securityencrypt sensitive data,secure APIs,role-based accessObservability- logs, metrics, traceability for audits and debugging
Extensibility- add new
channelsandtemplateswith minimal changes Idempotencyfor safe retrying failed deliveries
Constraints
- Channel limitations
SMS/emailprovider haverate limit&SLAs- Delivery channel characteristics
SMSis the most expensive & regulatedSMScost spikes drastically with volume- Push depends on
mobile infra(e.g.,FCM,Apple Push Notification service) - In-app can be fast but assumes user is online in the app
Cloud provider APIcalls (SES,Twilio,Firebase)High-availabilityinfra (queues,load balancers,workers)
Challenges, Estimating Scale, and Bottleneck
Estimating Scale
Daily Active User (DAU): 10 millionAverage events/user/day: 5Notification fan-out per event: 2 channels (e.g., email + push)Total notifications/day: 10 million 5 2 = 100 million- peak traffic multiplier: 3x (flash sales, incidents)
Challenges
Event bursthandling- spike during
flash sales,releases, orsystem-wide events- queue buildup & back pressure risks User preferencecomplexity- granular preferences (per
event type, perchannel) Latencyexpectations- users expect
instantfeedback —latencymust be low but not at the cost ofreliability Retry&Idempotentretriescan cause duplicate messages if not handledidempotently- failed external provider calls must not block the whole system
Security&PrivacyPIIlikeemailsandphone numbersmust be securely stored & transmitted- Must log activity without
leaking sensitive content
Bottlenecks
Event ingestion- high volume of incoming events → need
rate-limiting,buffering(Kafka,SQS, etc) - Template rendering
CPU-heavyif synchronous usecachingorpre-rendering- External provider APIs
latencyandrate-limited→ risk of throttling and timeoutsUser preferencelookup- high
QPS/RPS; might need caching layer (e.g.,Redis) - Monitoring & Logging:
- high cardinality data → risk of overwhelming observability stack
System Design Overview
CAP Trade-off
According to the non-functional requirements, we may have to choose AP in this application.
For most operations, users can afford eventually consistency.
However, the consistency is still important for the core operations (e.g., deduplication, user preference, etc). For these operations, they should be CP. It helps to decide the technical decision for the database.
- The database for
user preferenceneeds to beSQLto keep theACIDprotection - The database for the
deduplicationneeds to beSQLfor unique constraint (or useRedisSET NX)

Components Diagram
There are a few important components in the following diagram.
Event ingestor- Captures events from upstream services (e.g.,
order service,auth service) - Uses
rate-limiting(e.g., useRedisorAPI Gateway) andbuffering(e.g., Kafka, SQS) to handlehigh volume Notification orchestrator- Decide which notifications to trigger based on
eventanduser preferences(deduplication) - Coordinates with
Preference serviceandTemplate service Preference service- Stores user notification preferences (channels, event types, quiet hours)
- Users caching (e.g.,
Redis) for fast access Template service- Generates
localized messagesbased on event data - Caches templates for performance (e.g.,
Redis) Channel workers(email,SMS,push,in-app)- Handles delivery via dedicated workers for each channel
- Manages
retriesandfailures Dead-letter queue- Uses
dead-letter queueforundelivered messagesafterretries

Technical Stack & Infra
Event broker/Message broker
kafka(high throughput) orSQS(managed service)
Template rendering
HandlebarsorLiquid templating engine
Notification channels
SendGid(email),Twilio(SMS),FCM— Android,Apple Push Notification service— iOS (Push)
Database
PostgreSQLfor preferences,S3for template storage
Auto-scaling
horizontal Pod AutoscalingorKubernetes Event-Driven Autoscalingfor scaling workers
Deployment
microservicesonK8SorLambda(serverless)
Security
JWTauth,RBACfor admin APIs
Observability
Prometheus+Grafanafor monitoring,CloudWatchfor logs
Workflow
The following sequence diagram shows how components work together.

Send Notifications
Event source(e.g.,order service,auth service) sends events to theevent ingestorEvent ingestorsends events toevent brokerNotification orchestrator- Consume events from the
event broker - Retrieve the
user preferencefrom thePreference service - Retrieve the
localized messagesfrom theTemplate service - Send the notification to the
notification channel queues Channel workers- Consume the notification from the
notification channel queues - Call the
notification providersto send the notifications
Failure Handling for Notification Orchestrator
- When
Notification orchestratorfailed to retrieve data from thePreference service,Template service, or failed to send the notification to thenotification channel queues, the notification will be sent to theDead-letter queue
Cache Handling for Preference service/Template service
- Use the cache-aside strategy
Architecture Decision Records
ADR 1. Kafka as Event Broker over SQS
We use Kafka for the event broker because of the following considerations.
- We have to handle the high
QPS, 100 million notifications per day - We have to support the
message replying - The disadvantage for using
KafkaorAWS MSK(KafkainAWS) is we have to maintain the service by ourselves rather thanSQS
The following table is trade-off between Kafka and SQS.
[embed]
ADR 2. Notification Orchestrator as Central Coordinator over Choreography
choreographysaga pattern- no centralize management
- coordinate
sagaswith applyingpublish-subscribeprinciples - all services and channel workers consume notifications from the event queue
- push events to trigger the next action
orchestrationsaga pattern- centralize management
- coordinate
sagaswith a centralized controllermicroservices - Invoke to execute local
microservicestransactions in sequentially (could berequest/responseorevent-driven) - Execute saga transaction and manage them in centralized way and if one of the step is failed, then executes rollback steps with compensating transactions
We use orchestration because of the following considerations.
- The centralize management is easier to trace issues and debug
- Decouple services and channel workers
ADR 3. Dead Letter Queue for Undelivered Notifications
There are a few options for the failure handling.
- Infinite
retry+exponential backoff+jitter - Finite
retry+exponential backoff+dead letter queue
We use limited retry + exponential backoff+ dead letter queue because of the following considerations.
- Avoid the infinite
retryconsuming resources - We want to keep the failure messages in the
dead letter queuefor retrying
The following table is trade-off between 2 options.
[embed]
Reference
Summary
Thanks for your patient. I am Sean. I work as a software engineer.
This article is my note. Please feel free to give me advice if any mistakes. I am looking forward to your feedback.
- Subscribe me
- Recommended places for digital nomads
- The Daily Learning website
메타데이터
- post_id
- 0e5559bf9ad9
- slug
- notification-system-design-architecture-decision-records-0e5559bf9ad9
- url
- https://medium.com/a-layman/notification-system-design-architecture-decision-records-0e5559bf9ad9
- canonical_url
- https://medium.com/a-layman/notification-system-design-architecture-decision-records-0e5559bf9ad9
- author_url
- https://medium.com/@seanhsieh_63050
- status
- ok
- fetched_at
- 2026-06-10 08:17:25