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.