Multi-channel notification platform inspired by large companies' published designs: idempotent intake, preference- and template-aware routing with quiet hours and caps, per-channel queues with provider failover and dead letters, webhook-driven delivery tracking, and scheduled campaigns. A teaching design.
See why calling providers synchronously makes every caller slow and fragile.
What was missing: Nothing yet.
Why that's risky: Every caller waits on a provider round trip; a slow provider stalls checkout or sign-up, retries send duplicates, and a campaign burst overwhelms everything.
What gets added: One server that calls the email or SMS provider while the calling service waits.
Trade-offs: Simple, but the slowest provider sets everyone's latency.
Acknowledge requests immediately and never send the same notification twice.
What was missing: Providers were called inside the caller's request.
Why that's risky: Users get messages on channels they turned off, at 3 am, and as many as callers send.
What gets added: An ingest service that validates each request, drops duplicates by idempotency key, stores it and enqueues it, replying as soon as it's stored; a dispatcher sends from the queue.
Trade-offs: Callers get 'accepted', not 'delivered'.
Send the right message on the right channel at an acceptable time.
What was missing: No user preferences, templates or quiet hours.
Why that's risky: When a provider fails, jobs fail too, and failed jobs disappear.
What gets added: A router that checks each user's channel preferences, quiet hours and frequency caps, renders the template in their language, and puts jobs on per-channel queues with their own senders.
Trade-offs: Quiet hours delay some notifications; security codes and password resets bypass them.
Keep delivering when a provider fails, and never lose a notification silently.
What was missing: One provider per channel, and failed jobs vanished.
Why that's risky: Nobody knows whether a notification was actually delivered, and support can't check.
What gets added: Backup email and SMS providers that senders fail over to, retries with exponential backoff on every queue, and a dead-letter queue with a replayer for jobs that failed everywhere.
Trade-offs: Failover can deliver a message twice if the first provider was slow rather than failed; templates are written to tolerate that.
Know what was delivered, bounced or opened, and let support look it up.
What was missing: No delivery status.
Why that's risky: Scheduled sends and campaigns go out all at once, and callers aren't limited.
What gets added: Providers' webhooks feed a tracking service that records delivered, bounced, opened and unsubscribed status per notification and channel, plus a searchable delivery log for support.
Trade-offs: Statuses arrive when providers report them, sometimes minutes later.
Send at the right time, protect users from noisy callers, and watch every channel.
What was missing: No scheduling, no caller limits, no monitoring.
Why that's risky: Remaining risk is regional: queues and stores should fail over between regions.
What gets added: A scheduler that holds scheduled sends until their time and spreads campaigns over minutes, quotas per calling service, and monitoring of queue depth, provider errors, failovers and delivery rate.
Trade-offs: Spreading a campaign means the last recipients get it a few minutes later.
Require a client- or server-generated dedupe key. Store keys with outcome in the DB. On retries, return the recorded result. Workers use idempotency keys when calling providers to avoid duplicates.
Store preferences in a relational DB keyed by user and topic. Cache hot rows. At ingest, check preferences and quiet hours to select channels or schedule for later.
Use exponential backoff with jitter and a capped retry policy per channel. Route permanent failures to DLQ for inspection/replay with safeguards that re-check idempotency before sending again.
Abstract providers behind adapters. Track per-provider health and success rates; route using primary/secondary with circuit breakers. Fall back when SLA or error thresholds breach; restore automatically as health improves.
You're in the middle of an interview session. Leaving now will end your current attempt.
Explore concept overviews, real-system examples, key tradeoffs, and interview talking points for each roadmap section.
You've conquered this phase. These are the skills you now own: