Grokking the System Design Interview, Volume II
Vote

0% completed

Notification System: Requirements

Step 2: Clarify and Define Requirements

Functional Requirements

Non-Functional Requirements

Step 2: Clarify and Define Requirements

Step 1 named the parts of the system and the words we use for them. Now we agree on what this service must do, and on the limits it must meet. Every choice in the steps that follow is checked against this list.

Functional Requirements

Functional requirements
Functional requirements
  • Multi-channel delivery. Send notifications by email, SMS, mobile push, and in-app. One event can go out on one channel or on several.
  • Real-time and batched notifications. A chat message or an alert is a real-time notification. It should reach the user within about 1 to 2 seconds. The service must also handle bulk sends, like a daily digest or a marketing campaign. One of those can reach millions of users at once. Those are two different jobs. Bulk sends need their own batch path, driven by a schedule or a trigger. That path sits next to the one for one-off sends.
  • Message scheduling. A tenant can ask for a notification to go out at a future time. The request is stored. A scheduler part sends it when the time comes. For example, a meeting reminder can be queued to go out 10 minutes before the meeting.
  • Retry on failure. A send can fail on a channel for a short-lived reason. Provider downtime and network errors are the common ones. When that happens, the system retries after a short delay. The delay grows with each attempt. A delay that grows this way is called exponential backoff. What we get is at-least-once delivery. The system keeps trying, so a temporary problem does not lose a message.
  • User preferences and opt-out. A user can turn off a notification type, or a whole channel. The system checks those settings and skips what was turned off. If a user disabled SMS, or opted out of promotional email, those channels are not used. A user can also pick a channel per alert type, like SMS for critical alerts and email for newsletters.
  • Multi-tenant support. Each tenant's data is kept apart. A tenant can only send to its own users and only see its own data.
  • Notification content and templates. A tenant can define a message template for each notification type. A template holds placeholders, like "Hello {name}, your order {order_id} shipped." The service fills in the data for each event.
  • No channel prioritization. All channels are treated equally. When an event goes out on several channels, each is delivered on its own, and none waits for another.
  • In-app notification management. Notifications can appear inside the application, like the bell icon in a social app. So the system stores notifications in a database, and a user can fetch their list later. It can also push an in-app alert straight to an active session, over a WebSocket or a similar connection.
  • API for notification producers. Applications call a clean API to create notification requests. Each request names the users to notify, the content, and the channels to use. The content is often a template id plus data. The API handles a single recipient, and also bulk sends to a list of users or a user segment.

Two items on that list shape everything that follows. Preferences mean the service cannot simply send what a tenant asks it to send. No channel prioritization means the design has to keep the channels apart rather than rank them.

Non-Functional Requirements

Non-functional requirements
Non-functional requirements

Scalability. The system must handle web-scale load. That means millions of users and very high notification volumes. A single social media tenant could produce hundreds of millions of notifications a day. So the design must scale horizontally, meaning we add machines to handle more load. No single part may become a bottleneck.

High throughput. Both writes and reads arrive at a high rate. At peak, the system might take in tens of thousands of notification events per second. Picture a viral post, or a major sale event.

Low latency. For real-time channels, the delay from event to user device should be low. Ideally it is under a second. Email and SMS can tolerate a small delay, under about a minute. The gap between those two targets is about where the person is. A push arrives on a screen somebody is looking at right now, so a delay is visible. An email is read later, and nobody can tell when it was sent.

High availability. The service should almost never be down. Aim for 99.99% uptime. Some notifications are critical, like password resets, security alerts, and order confirmations. So the system needs redundant parts across data centers or availability zones (AZs). It must keep working when a part fails.

Durability. No notification is lost. Once the system accepts an event, it is queued or stored. Even if servers crash, the notification is still delivered later.

Ordering. Inside one user's feed, notifications should appear in the order they happened. Two events for the same user must not swap places in the in-app feed. The order may take a moment to settle, but it must end up right. Exact ordering across the whole system is not required. That promise is per user rather than global, which makes it much cheaper to keep.

Multi-tenant isolation and security. Two separate promises live under this heading. The first is about load. One tenant's heavy traffic or failure must not spread to the other tenants. That may mean a rate limit per tenant, or separate partitions per tenant. The second is about privacy. Data is partitioned or tagged by tenant. Tenant A can never read tenant B's notifications or user data. Every tenant must also authenticate securely when it calls the API.

Flexibility and extensibility. Adding a new channel, like WhatsApp or push for a new platform, should not mean redesigning the system. The same goes for adding features later, like sending at a set time or batching into daily digests.

With these requirements, we have a clear target. We need a fast, reliable service that takes events from every tenant. It delivers on the right channels, and it respects user preferences at very large scale.

Next: Step 3, where those requirements become numbers.

Reading Progress

0%


Vote for new content

On This Page

Step 2: Clarify and Define Requirements

Functional Requirements

Non-Functional Requirements