Notifications Architecture for SaaS at Pre-Seed Stage

Notifications are how your product communicates with users outside of active sessions. At pre-seed, most teams underinvest in notifications — they send a welcome email and nothing else — and then wonder why activation and retention are low. Notifications done well drive users back into the product at the right moment. Notifications done poorly train users to ignore or unsubscribe from everything you send.

This guide covers the architecture decisions pre-seed teams need to make: which channels to support, how to separate transactional from product notifications, and how to build user preference controls without overengineering.

📡 Notification Types and Channel Selection

Notification TypeChannelPre-Seed PriorityExample
TransactionalEmailRequiredWelcome email, password reset, billing receipts
Product / activityEmail or in-appHigh"Your report is ready", "Someone commented on your doc"
Onboarding dripEmailHighDay 1, Day 3, Day 7 activation nudges
Digest / summaryEmailMediumWeekly usage summary, team activity digest
In-app alertsIn-app banner or toastMediumNew feature announcement, account limit warning
Push notificationsBrowser push or mobile pushLow (add later)Real-time alerts for time-sensitive events

At pre-seed, build email and in-app. Skip push notifications until you have evidence that email alone is insufficient to re-engage your users — which is rare at early stage.

📧 Transactional Email Stack

Transactional emails (welcome, password reset, billing confirmation, account alerts) must be reliable, templated, and delivered immediately. They are not marketing emails — they are product functionality delivered via email.

Pre-seed transactional email stack:

// Resend transactional email example
import { Resend } from 'resend';
const resend = new Resend(process.env.RESEND_API_KEY);

await resend.emails.send({
  from: 'no-reply@yourproduct.com',
  to: user.email,
  subject: 'Welcome to YourProduct',
  react: WelcomeEmail({ name: user.name }),
});

🔔 In-App Notifications

In-app notifications appear inside the product: a notification bell with a dropdown, a toast/snackbar for immediate feedback, or a banner for account-level alerts. At pre-seed, you need two patterns: toasts for immediate feedback and a notification feed for persistent alerts.

Toast notifications: Used for action confirmations ("Report saved", "Member invited") and error alerts. Render client-side, dismissed automatically after 3–5 seconds. No database storage required — state lives in the component.

Notification feed (bell icon): Used for asynchronous product events ("Someone commented on your document", "Your export is ready"). Requires database storage:

CREATE TABLE notifications (
  id         UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  user_id    UUID NOT NULL REFERENCES users(id),
  type       TEXT NOT NULL,  -- 'comment', 'export_ready', 'mention'
  payload    JSONB,          -- event-specific data
  read_at    TIMESTAMPTZ,    -- null = unread
  created_at TIMESTAMPTZ DEFAULT NOW()
);

Poll this table on page load and mark notifications read when the user opens the feed. Real-time delivery (WebSocket or SSE) is a nice-to-have — add it when user complaints about delayed notifications appear, not before.

⚙️ User Notification Preferences

Build notification preferences before users ask for them. The absence of preferences drives unsubscribes — users who cannot control what they receive will opt out of everything.

Pre-seed minimum preference model:

Store preferences on the user record as a JSON column:

ALTER TABLE users ADD COLUMN notification_preferences JSONB DEFAULT
  '{"product_emails": true, "marketing_emails": true}'::jsonb;

What to Do Next

If you have no notification system: start with the transactional email stack — welcome email, password reset, billing receipt — using Resend or Postmark. These are product requirements, not marketing. Once transactional is working, add an onboarding drip sequence (Day 1, Day 3, Day 7) designed to drive users to their activation milestone. If you have email but no in-app notifications: add the notifications table and a bell icon with unread count. Users who receive a notification in-app are significantly more likely to return to the product than users who receive only email.