Транспорт бэкенда

System Design: Notification System

WhatsApp отправляет 100 миллиардов сообщений в день. Facebook - миллиарды нотификаций. Как это работает без того, чтобы OTP коды ждали в очереди за рекламой чёрной пятницы?

  • **Airbnb** перешла с монолитного notification service на priority queues - время доставки booking confirmation упало с 45s до 3s в пиковые периоды
  • **LinkedIn** обнаружила, что frequency capping (не более 3 нотификаций в день) повысила retention на 8% - меньше пользователей отключали нотификации
  • **Pinterest** использует Flink для real-time batching нотификаций - группирует 'X людей лайкнули ваш пин' вместо отдельного push на каждый лайк, снизив объём в 10x

Requirements

Notification System - это инфраструктура, которая доставляет сообщения пользователям через несколько каналов: push (iOS/Android), email, SMS, in-app. На масштабе Facebook - 2.5 млрд пользователей, миллиарды нотификаций в день. Ключевое отличие от обычного messaging: нотификации могут быть критичными (OTP, payment alert) или некритичными (маркетинг), и эти категории требуют разной обработки.

Функциональные требования: отправка через push/email/SMS/in-app, шаблонизация с переменными, расписание (scheduled delivery), группировка нотификаций. Нефункциональные: 10M нотификаций/мин пиковая нагрузка, p99 latency < 5s для критичных, < 30min для маркетинговых, гарантия at-least-once delivery.

Почему push-нотификации и SMS требуют разных SLA по latency?

Multi Channel

Каждый канал - отдельный воркер с собственным адаптером. Push через APNs (Apple) и FCM (Google) - бинарный HTTP/2 протокол, batch до 1000 токенов. Email через SMTP или API (SendGrid, AWS SES) - ограничения на sending domain reputation. SMS через SMPP gateway (Twilio, Vonage) - дороже $0.005-0.05 за сообщение, fallback логика обязательна.

User preference service хранит opt-in/opt-out по каждому каналу. Нотификация routing: 1) проверить user preferences, 2) выбрать каналы, 3) применить quiet hours (не слать SMS в 2am), 4) применить frequency capping. Twilio отчитывается: email open rate 20-25%, push open rate 7-10%, SMS read rate 98% в первые 3 минуты.

FCM возвращает ошибку `messaging/registration-token-not-registered` для токена. Что нужно сделать?

Priority Routing

Priority queues - ключевой механизм notification system. Критичные (OTP, payment alert, security) не должны стоять в очереди за маркетинговыми рассылками. Типичная схема: 3 приоритета - CRITICAL (dedicated workers, SLA < 5s), HIGH (быстрая очередь, SLA < 30s), LOW (batch-очередь, SLA < 30min). RabbitMQ поддерживает x-max-priority, Kafka - отдельные топики per priority.

Template engine - отдельный слой перед отправкой. Шаблоны хранятся в БД (title, body, variables, channel-specific variants). Рендеринг: Handlebars/Mustache с sandboxing. A/B тестирование нотификаций: 10% трафика - вариант B, остальные - вариант A. Facebook проводит 1000+ A/B тестов нотификаций одновременно для оптимизации engagement.

Kafka vs RabbitMQ для priority queues нотификаций. Что правильно?

Rate Limiting

Notification rate limiting работает на двух уровнях: per-provider (APNs ограничивает 2500 notifications/s per app, Twilio SMS - configurable, но платно) и per-user (frequency capping - не более 3 маркетинговых push в день, иначе пользователь отключит нотификации). LinkedIn обнаружил, что снижение частоты email нотификаций на 30% повышает CTR на 20%.

Quiet hours - обязательный компонент. Timezone-aware: хранить timezone пользователя, не отправлять LOW/HIGH категории с 22:00 до 08:00 локального времени. CRITICAL (OTP, security) игнорирует quiet hours. При попадании в quiet hours нотификация либо discarded (маркетинг) либо scheduled на утро (high priority).

Пользователь в UTC+5. Quiet hours 22:00-08:00 локального. Нотификация создаётся в 20:00 UTC. Что происходит?

Delivery Tracking

Delivery tracking замыкает feedback loop: sent -> delivered -> opened -> actioned. APNs и FCM возвращают delivery receipts синхронно (HTTP/2 response). Email требует pixel tracking (1x1 gif) или click tracking через redirect. SMS delivery reports приходят через webhook от provider асинхронно. Данные хранятся в ClickHouse или BigQuery для аналитики - сотни миллиардов строк events.

Retry logic: при failed delivery - exponential backoff (1s, 2s, 4s, max 3 попытки для CRITICAL, 1 попытка для LOW). Failed нотификации → DLQ → alert если DLQ rate > 1%. Idempotency: notification_id как идемпотентный ключ предотвращает дублирование при retry. APNs возвращает `apns-id` для deduplication на стороне Apple.

Notification system - это просто обёртка над APNs/FCM/SendGrid, достаточно вызвать их API напрямую

Notification platform - это полноценная инфраструктура: priority queues, frequency capping, template engine, delivery tracking, retry logic, provider failover. Прямой вызов APNs без этих слоёв не масштабируется и создаёт плохой user experience

Без frequency capping пользователи отключают нотификации. Без priority queues OTP ждёт за маркетинговой рассылкой. Без delivery tracking нет данных для оптимизации. Facebook строил notification infrastructure 5+ лет и выделил в отдельную команду

Email open rate измеряется через pixel tracking. Какая главная проблема с этой метрикой?

Итоги

  • **Priority queues** разделяют CRITICAL (OTP, security) от LOW (marketing) - отдельные воркеры с разными SLA, чтобы важные нотификации не ждали в общей очереди
  • **Frequency capping + quiet hours** - user-centric ограничения, которые парадоксально повышают engagement: меньше нотификаций → меньше opt-out → выше реальный reach
  • **Delivery tracking через ClickHouse** замыкает feedback loop: queued → sent → delivered → opened → clicked, с корректировкой на Apple Mail Privacy Protection

Связанные темы

Notification system опирается на несколько паттернов из курса:

  • Dead Letter Queue — Failed нотификации уходят в DLQ с retry policy - тот же паттерн exponential backoff из урока про DLQ
  • Rate Limiting (API Gateway) — Frequency capping - это rate limiting per user, те же алгоритмы Token Bucket и Sliding Window из урока про API Gateway
  • Backpressure — При пиковой нагрузке (breaking news) воркеры LOW priority останавливаются - классическая load shedding стратегия из урока про backpressure

Вопросы для размышления

  • Notification system обещает at-least-once delivery. Что произойдёт если пользователь получит один и тот же OTP код дважды из-за retry? Как спроектировать idempotency на клиентской стороне?
  • Apple Push Notification service (APNs) недоступен 10 минут. Какова стратегия: буферизировать нотификации и отправить все разом, или discardить и предупредить пользователей через другой канал?
  • Как спроектировать A/B тестирование нотификаций, чтобы пользователь из группы A не получил нотификацию из группы B при ретрае, и чтобы статистика была statistically significant?

Связанные уроки

  • net-55-message-queues
System Design: Notification System

0

1

Войти