Problem statement
Design the reminder engine for a to-do and task app: users attach reminders to tasks ("nudge me at 9am", "an hour before it's due", "every weekday morning"), and the system fires each one on time and delivers it to their chosen channels. It is the piece that makes a task actually resurface at the right moment.
Operating context. Reminders vastly outnumber fires — most sit dormant for days or weeks. Fire times cluster hard on round numbers (the top of the hour, 9:00 local). A fired reminder can be snoozed to a later time, cancelled when its task is completed, or, if recurring, must schedule its next occurrence. Delivery goes to whichever channels the user picked. A late reminder is an annoyance; a lost or duplicated reminder erodes trust.
Out of scope. The task/to-do data model and app UI, the actual push/email/SMS transport internals (assume channel adapters exist), user authentication, and per-message content rendering. Assume a delivery service accepts a (user, channel, payload) and best-effort delivers it.
What to produce. A high-level architecture covering: how pending reminders are stored and efficiently queried by fire time without scanning everything; the dispatch path and how you tame the top-of-the-hour thundering herd; how you get effectively-once delivery from an at-least-once pipeline; how recurrence, snooze, and cancel interact; and the failure story when a dispatcher dies mid-fire. Sketch the components and the life of one reminder from set to fired; we will probe specifics in checkpoints.
Functional requirements
- Accept a reminder with a fire time (absolute, or relative to a task's due date) targeting a specific user.
- Fire each reminder close to its scheduled time and, under normal operation, effectively once.
- Support snoozing a fired reminder to a new time and cancelling reminders when their task completes.
- Support recurring reminders (daily, weekly, custom) that schedule the next occurrence after each fire.
- Fan a fired reminder out to the user's selected delivery channels (push, email, in-app).
Non-functional requirements
- Manage 2 billion pending reminders, of which roughly 50 million fire on a typical day.
- Fire within p99 of 10 s of the scheduled time under normal load.
- Sustain about 600 fires/sec on average, bursting to 50000/sec at the top of a popular hour.
- At-least-once delivery with dedup so a user never receives the same reminder twice within 5 minutes.
- 99.9% availability; a delayed reminder is degraded service, a silently lost reminder is a failure.
- Ingest 20000 new or updated reminders/sec at peak.
Topics
- System Design HLD
- Scheduling Timers
- Infra Queue
- Data Partitioning
- Patterns Idempotency