Bird
Raised Fist0
LLDsystem_design~15 mins

Notification on state change in LLD - Deep Dive

Choose your learning style10 modes available

Start learning this pattern below

Jump into concepts and practice - no test required

or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Overview - Notification on state change
What is it?
Notification on state change is a system design concept where a system sends alerts or messages whenever the status of an object or process changes. This helps other parts of the system or users to react immediately to important updates. It ensures timely communication without constant checking. For example, a delivery app notifying you when your package status changes from 'shipped' to 'out for delivery'.
Why it matters
Without notifications on state change, systems or users would have to repeatedly check for updates, wasting resources and causing delays. This concept solves the problem of inefficiency and slow reactions in dynamic environments. It improves user experience and system responsiveness by pushing updates only when needed. Imagine missing a critical alert because you didn’t check often enough.
Where it fits
Before learning this, you should understand basic event-driven programming and state management. After this, you can explore advanced event streaming, message queues, and real-time system architectures. This concept is a stepping stone to building scalable, reactive systems.
Mental Model
Core Idea
A system watches for changes and instantly tells interested parties only when something important changes.
Think of it like...
It's like a smoke detector that stays quiet until it senses smoke, then immediately rings an alarm to alert everyone nearby.
┌───────────────┐       ┌───────────────┐       ┌───────────────┐
│   State       │──────▶│ Change        │──────▶│ Notification  │
│   Monitor     │       │ Detection     │       │ Dispatcher    │
└───────────────┘       └───────────────┘       └───────────────┘
                                │                       │
                                ▼                       ▼
                         ┌───────────────┐       ┌───────────────┐
                         │ State Change  │       │ Subscribers/  │
                         │ Event         │──────▶│ Users         │
                         └───────────────┘       └───────────────┘
Build-Up - 7 Steps
1
FoundationUnderstanding system state basics
🤔
Concept: Learn what system state means and how it can change over time.
System state is the current condition or status of an object or process, like a light being ON or OFF. Changes happen when something updates this condition, such as a user turning the light switch. Recognizing state is key to knowing when to notify others.
Result
You can identify when and what changes in a system's state.
Understanding state is the foundation for knowing when notifications should be sent.
2
FoundationWhat triggers a notification
🤔
Concept: Learn the conditions that cause a notification to be sent.
A notification triggers only when the system detects a change in state that matters. For example, a door sensor sends a notification only when the door opens or closes, not continuously. This avoids unnecessary alerts.
Result
You know how to define meaningful state changes that require notifications.
Knowing what triggers notifications prevents overload and keeps communication relevant.
3
IntermediateEvent-driven notification flow
🤔Before reading on: do you think notifications are sent by checking state periodically or by reacting instantly to changes? Commit to your answer.
Concept: Notifications are best sent by reacting instantly to state changes using events.
Instead of checking state repeatedly (polling), systems use events that fire immediately when state changes. This event-driven approach improves efficiency and responsiveness. For example, a temperature sensor sends an event when temperature crosses a threshold, triggering a notification.
Result
You understand how event-driven systems send notifications promptly and efficiently.
Understanding event-driven flow helps design systems that respond quickly without wasting resources.
4
IntermediateSubscriber pattern for notifications
🤔Before reading on: do you think notifications are sent to all users or only to those interested? Commit to your answer.
Concept: Notifications should be sent only to subscribers interested in specific state changes.
The subscriber pattern means users or components register interest in certain state changes. When a change happens, only those subscribers get notified. This avoids spamming everyone and keeps communication targeted.
Result
You can design systems that send notifications selectively to interested parties.
Knowing how to use subscribers improves scalability and user experience by reducing noise.
5
IntermediateHandling notification delivery reliability
🤔Before reading on: do you think notifications always arrive successfully or can they fail? Commit to your answer.
Concept: Notification delivery can fail and systems need ways to ensure reliability.
Networks or systems can fail, causing notifications to be lost. Techniques like retries, acknowledgments, and durable queues help ensure notifications reach subscribers. For example, a message queue stores notifications until confirmed delivered.
Result
You understand how to build reliable notification delivery mechanisms.
Knowing delivery challenges prevents lost notifications and improves system trustworthiness.
6
AdvancedScaling notifications for many users
🤔Before reading on: do you think a single server can handle millions of notifications or do we need special design? Commit to your answer.
Concept: Large-scale systems require distributed architectures to handle many notifications efficiently.
When millions of users subscribe, a single server can't handle all notifications. Systems use load balancers, distributed message brokers, and partitioned subscriber groups to scale. For example, Kafka or RabbitMQ can distribute notification events across servers.
Result
You can design notification systems that scale to millions of users without delays.
Understanding scaling techniques is crucial for building real-world, high-volume notification systems.
7
ExpertOptimizing notification latency and consistency
🤔Before reading on: do you think notifications always arrive instantly and in order? Commit to your answer.
Concept: Balancing speed and order of notifications requires careful design tradeoffs.
Some systems prioritize low latency, sending notifications immediately but risking out-of-order delivery. Others ensure strict order but add delay. Techniques like vector clocks, causal ordering, and eventual consistency help manage these tradeoffs. For example, chat apps may accept slight delays to keep message order correct.
Result
You understand how to optimize notification systems for both speed and consistency.
Knowing these tradeoffs helps build systems that meet specific user needs and expectations.
Under the Hood
Internally, the system monitors state variables or data stores for changes using watchers or triggers. When a change occurs, it creates an event object describing the change. This event is sent to a notification dispatcher, which looks up subscribers interested in this event type. The dispatcher then sends messages via channels like push notifications, emails, or API calls. To ensure delivery, the system may use message queues that store events until confirmed received.
Why designed this way?
This design evolved to avoid inefficient polling and reduce unnecessary communication. Early systems used constant checks, wasting resources. Event-driven and subscriber models emerged to improve responsiveness and scalability. Message queues and retries were added to handle unreliable networks and ensure no notifications are lost.
┌───────────────┐      ┌───────────────┐      ┌───────────────┐
│ State Store   │─────▶│ Change Watcher│─────▶│ Event Creator │
└───────────────┘      └───────────────┘      └───────────────┘
                                │                      │
                                ▼                      ▼
                         ┌───────────────┐      ┌───────────────┐
                         │ Notification  │─────▶│ Message Queue │
                         │ Dispatcher    │      └───────────────┘
                         └───────────────┘              │
                                │                        ▼
                                ▼                 ┌───────────────┐
                         ┌───────────────┐        │ Subscriber    │
                         │ Delivery      │◀───────│ Receivers     │
                         │ Confirmation  │        └───────────────┘
                         └───────────────┘
Myth Busters - 4 Common Misconceptions
Quick: Do notifications always arrive instantly and never get lost? Commit to yes or no.
Common Belief:Notifications are guaranteed to arrive instantly and never fail.
Tap to reveal reality
Reality:Network issues, server failures, or bugs can delay or lose notifications. Systems must handle retries and confirmations.
Why it matters:Assuming perfect delivery leads to missed alerts and system failures in real-world conditions.
Quick: Do you think all users should get every notification? Commit to yes or no.
Common Belief:Every notification should be sent to all users to keep everyone informed.
Tap to reveal reality
Reality:Sending all notifications to everyone causes overload and irrelevant alerts. Targeted delivery to subscribers is essential.
Why it matters:Ignoring selective delivery leads to poor user experience and wasted resources.
Quick: Is polling better than event-driven notification? Commit to which is more efficient.
Common Belief:Polling the system regularly is the best way to detect state changes for notifications.
Tap to reveal reality
Reality:Polling wastes resources and causes delays. Event-driven notifications are more efficient and timely.
Why it matters:Using polling in large systems causes scalability and performance problems.
Quick: Do you think notification order is always preserved? Commit to yes or no.
Common Belief:Notifications always arrive in the exact order state changes happen.
Tap to reveal reality
Reality:Due to network delays and distributed systems, order can be out of sync unless special measures are taken.
Why it matters:Assuming order can cause bugs in systems relying on sequence, like financial transactions.
Expert Zone
1
Notification systems often balance between push and pull models depending on network conditions and client capabilities.
2
Handling duplicate notifications gracefully is critical, as retries can cause repeated messages.
3
Latency optimization sometimes sacrifices strict consistency, requiring careful design to meet user expectations.
When NOT to use
Notification on state change is not ideal for systems where state changes are irrelevant or too frequent, causing notification storms. In such cases, batch updates or periodic summaries are better. Also, for very simple or static systems, polling might be simpler and sufficient.
Production Patterns
Real-world systems use message brokers like Kafka or RabbitMQ to decouple state change detection from notification delivery. They implement subscriber filtering, backpressure handling, and dead-letter queues for failed notifications. Mobile apps use push notification services integrated with this architecture for real-time alerts.
Connections
Observer Pattern
Notification on state change builds on the observer design pattern where observers subscribe to subjects to get updates.
Understanding observer pattern clarifies how subscribers receive notifications only when state changes.
Event-Driven Architecture
Notification on state change is a practical application of event-driven architecture principles.
Knowing event-driven architecture helps design scalable and responsive notification systems.
Human Reflexes in Neuroscience
Similar to how neurons send signals instantly on stimuli, notification systems send alerts on state changes.
Recognizing this biological parallel helps appreciate the efficiency and immediacy required in notification systems.
Common Pitfalls
#1Sending notifications to all users regardless of interest.
Wrong approach:for user in all_users: send_notification(user, event)
Correct approach:for user in subscribers[event.type]: send_notification(user, event)
Root cause:Misunderstanding the importance of selective delivery and subscriber filtering.
#2Using polling to detect state changes for notifications.
Wrong approach:while True: if state_changed(): send_notification() sleep(5)
Correct approach:on_state_change_event(event): send_notification(event)
Root cause:Not knowing event-driven mechanisms and relying on inefficient polling.
#3Not handling failed notification deliveries.
Wrong approach:send_notification(user, event) # no retry or confirmation
Correct approach:if not send_notification(user, event): retry_send(user, event)
Root cause:Ignoring network unreliability and lack of delivery guarantees.
Key Takeaways
Notification on state change improves system responsiveness by sending alerts only when important updates occur.
Event-driven and subscriber patterns are key to efficient and scalable notification systems.
Reliable delivery requires handling failures with retries and confirmations to avoid lost notifications.
Scaling notifications for many users demands distributed architectures and message brokers.
Balancing notification latency and consistency involves tradeoffs that must match system requirements.

Practice

(1/5)
1. What is the main purpose of a notification system on state change in software design?
easy
A. To inform interested components immediately when data changes
B. To store data permanently in a database
C. To increase the size of the application
D. To delay updates until the user refreshes manually

Solution

  1. Step 1: Understand the role of notifications

    Notifications alert parts of a system or users when something important changes.
  2. Step 2: Identify the purpose of state change notifications

    They ensure components get updates immediately without waiting or manual refresh.
  3. Final Answer:

    To inform interested components immediately when data changes -> Option A
  4. Quick Check:

    Notification = Immediate update [OK]
Hint: Notifications alert on change, not store or delay [OK]
Common Mistakes:
  • Confusing notification with data storage
  • Thinking notifications delay updates
  • Assuming notifications increase app size
2. Which of the following is the correct method name to notify observers in a typical observer pattern implementation?
easy
A. unsubscribe()
B. updateState()
C. subscribe()
D. notifyObservers()

Solution

  1. Step 1: Recall observer pattern methods

    Common methods include subscribe, unsubscribe, and notifyObservers.
  2. Step 2: Identify the method that sends updates

    notifyObservers() is used to alert all subscribed observers about changes.
  3. Final Answer:

    notifyObservers() -> Option D
  4. Quick Check:

    Notify method = notifyObservers() [OK]
Hint: Notify method usually named notifyObservers() [OK]
Common Mistakes:
  • Confusing subscribe with notify
  • Using updateState() which changes state, not notify
  • Mixing unsubscribe with notification
3. Consider this simplified code snippet for a notification system:
class Subject:
    def __init__(self):
        self.observers = []
    def subscribe(self, observer):
        self.observers.append(observer)
    def notify(self, message):
        for obs in self.observers:
            obs.update(message)

class Observer:
    def update(self, message):
        print(f"Received: {message}")

subject = Subject()
obs1 = Observer()
subject.subscribe(obs1)
subject.notify("State changed")
What will be the output when subject.notify("State changed") is called?
medium
A. Error: update method missing
B. No output
C. Received: State changed
D. Received: None

Solution

  1. Step 1: Trace subscription and notification

    Observer obs1 is subscribed to subject, so it is in the observers list.
  2. Step 2: Check notify method behavior

    notify calls update on each observer with the message "State changed".
  3. Final Answer:

    Received: State changed -> Option C
  4. Quick Check:

    Observer prints message on notify [OK]
Hint: Subscribed observers receive and print messages [OK]
Common Mistakes:
  • Assuming notify does nothing without explicit call
  • Thinking update method is missing
  • Expecting no output if observers list is empty
4. In the following code, what is the main issue that prevents observers from receiving notifications?
class Subject:
    def __init__(self):
        self.observers = set()
    def subscribe(self, observer):
        self.observers.add(observer)
    def notify(self, message):
        for obs in self.observers:
            obs.receive(message)

class Observer:
    def update(self, message):
        print(f"Got: {message}")

subject = Subject()
obs1 = Observer()
subject.subscribe(obs1)
subject.notify("Update")
medium
A. Observers are stored in a set instead of a list
B. Method notify calls obs.receive but Observer has update method
C. subscribe method uses add instead of append
D. Observer class is missing

Solution

  1. Step 1: Check method called in notify

    notify() calls obs.receive(message).
  2. Step 2: Check Observer class methods

    Observer defines update(message), but no receive() method.
  3. Final Answer:

    Method notify calls obs.receive but Observer has update method -> Option B
  4. Quick Check:

    Method name mismatch causes AttributeError [OK]
Hint: Check method names called vs defined in observers [OK]
Common Mistakes:
  • Confusing set vs list for storing observers
  • Ignoring method name mismatches
  • Assuming missing class when it exists
5. You are designing a scalable notification system for state changes in a distributed application. Which design choice best supports efficient notifications to thousands of subscribers without blocking the main process?
hard
A. Use asynchronous message queues to dispatch notifications
B. Notify all subscribers synchronously in a loop
C. Store notifications in a database and poll subscribers
D. Send notifications only when the system restarts

Solution

  1. Step 1: Understand scalability needs

    Thousands of subscribers require non-blocking, efficient notification delivery.
  2. Step 2: Evaluate design options

    Synchronous loops block main process; polling adds delay; restart notifications are impractical.
  3. Step 3: Identify best practice

    Asynchronous message queues decouple notification sending, allowing scalable, fast delivery.
  4. Final Answer:

    Use asynchronous message queues to dispatch notifications -> Option A
  5. Quick Check:

    Async queues = scalable notifications [OK]
Hint: Async queues handle many subscribers efficiently [OK]
Common Mistakes:
  • Using synchronous loops causing delays
  • Relying on polling which is slow
  • Sending notifications only on restart