Script Valley
Interview Prep: System Design Rounds
Designing Real SystemsLesson 5.3

How to design a notification system

push vs pull, notification fanout, message queues, multi-channel delivery, retry logic, notification templates, user preference management

Notification System Architecture

A notification system must deliver messages across multiple channels (push, email, SMS) reliably without blocking the main application flow.

Core Architecture

  1. Application generates an event (order placed, mention, follow)
  2. Event is published to a message queue (Kafka, SQS)
  3. Notification service consumes events and determines which users to notify
  4. Worker pools handle delivery per channel

Push vs Pull

  • Push: server sends notification to device (FCM for Android, APNs for iOS). Low latency. Device must be registered.
  • Pull: client polls for new notifications. Simpler but higher latency and server load.

Fanout at Scale

# Fanout approach for a post with 10M followers
# Option 1: Fanout on write (precompute) - fast reads, slow writes
def on_post_created(post):
    followers = db.get_followers(post.user_id)  # 10M users
    for follower_id in followers:
        queue.push(create_notification(follower_id, post))

# Option 2: Fanout on read - slow reads, fast writes
def get_notifications(user_id):
    following = db.get_following(user_id)
    return db.get_recent_posts(following, limit=20)

Retry and Deduplication

Delivery failures are common (expired device tokens, temporary service outages). Use exponential backoff and idempotency keys to prevent duplicate notifications on retries.

Up next

How to design a news feed system like Twitter or Instagram

Sign in to track progress