2.12.2 Notifications — Delivery — Real-time, Email, Retries

Notification delivery is decoupled from notification creation to ensure reliability and resilience. Once a notification is recorded, delivery mechanisms operate independently and may succeed or fail without affecting the underlying notification record. This design guarantees visibility through the Notification Center even when external transports are unavailable.

Delivery Channels

Notifications may be delivered through one or more channels based on user preferences, notification category, and tenant policy.

Supported channels:

Real-time in-application delivery

Email delivery

Deferred or batched delivery

Each channel maintains its own delivery state.

Real-time Delivery

Real-time delivery provides immediate visibility inside the application. Notifications are published to connected clients using a push-based mechanism. If no active connection exists, delivery is deferred to retrieval via the Notification Center.

Characteristics:

Low-latency best-effort delivery

No dependency on client acknowledgment

Automatic fallback to persistent storage

Example broadcast:

broadcast(new NotificationBroadcast($notification));

Email Delivery

Email delivery ensures notifications reach users outside active sessions. Emails are generated from templates and processed asynchronously through the queue system.

Email behavior:

Queued execution

Retry on transient transport failures

Suppression based on user preferences or notification state

Example dispatch:

Mail::to($user->email)->queue(new NotificationMail($notification));

Retry Strategy

Delivery attempts follow a deterministic retry strategy. Transient failures trigger retries with exponential backoff, while permanent failures terminate delivery attempts without deleting the notification.

Retry rules:

Configurable attempt limits

Backoff between attempts

Explicit failure classification

Example retry guard:

if ($delivery->attempts >= $maxAttempts) { $delivery->fail('max_attempts_exceeded'); }

Delivery State Tracking

Each notification maintains per-channel delivery state. States are immutable once finalized and are retained for diagnostics and audit purposes.

Tracked states:

Pending

Delivered

Failed

Suppressed

Partial delivery success is explicitly represented.

Idempotency and Deduplication

All delivery handlers are idempotent. Reprocessing a delivery job does not result in duplicate user-facing messages.

Example idempotency check:

if ($delivery->isDelivered()) { return; } $delivery->markDelivered();

User Preferences and Policies

Delivery respects user-defined preferences and tenant-level policies such as muted channels, quiet hours, or delivery restrictions. These rules are evaluated at dispatch time.

Security and Isolation

Delivery processes run within strict tenant scope. Outbound payloads are minimized, and sensitive data is excluded from external transports. Access to delivery logs and diagnostics is restricted to authorized roles only.