Architecture notebook

Event-driven notifications / Design note (conceptual)

Notifications that survive a broker restart

Notifying users directly inside a business transaction couples delivery to the transaction, so a slow SMS gateway becomes a slow checkout. Publishing an event and delivering it separately keeps the two failure domains apart.

  1. 01Domain event
  2. 02Outbox
  3. 03Dispatcher
  4. 04Channel adapter
Commit with the outbox → publish → deliver with retries

01 Write the event with the transaction

The domain change and its outbox row commit together, so an event cannot be lost after a successful business write or published for a rolled-back one.

02 Separate dispatch from delivery

A dispatcher reads the outbox, resolves user preferences and locale, and fans out to channel adapters. Each adapter owns its own provider quirks — templates, rate limits, and payload shapes.

03 Reliability: at-least-once plus deduplication

Retries with backoff cover transient provider failure. Because delivery is at-least-once, each notification carries a stable key and the adapter records it, so a repeat is dropped rather than sent twice.

04 Scale: partition by recipient, isolate slow channels

Partitioning by user keeps per-user ordering while allowing parallel consumers. Slow channels get their own queue and concurrency budget so email backlog cannot delay a one-time password.

05 Trade-off: eventual delivery and more moving parts

The user may be notified seconds after the action, and the system gains an outbox, a dispatcher, and per-channel state to operate. Worth it wherever the business transaction matters more than the message.