Skip to main content

Notification Delivery Storage

Summary

NotificationDeliveryAttempts records one append-only row per delivery attempt against a channel provider, including timing and any error.

Audience

Engineers, architects, QA, support and security reviewers.

Reference Content

The verified reference material for this topic is set out in the sections below.

Ownership

Owned by NotificationDbContext. Written by the dispatcher's attempt recorder on every try and by the template test endpoint's live-send path. Read by the attempts endpoint.

Columns

ColumnTypeConstraint
IdGUIDPrimary key
NotificationMessageIdGUIDPlain value, no constraint
AttemptNumberintOne-based
ChannelstringMax length 40, required
ProviderstringMax length 60, required
StatusstringMax length 40, required
ErrorstringMax length 2000, nullable
StartedOnUtctimestamp
CompletedOnUtctimestamp
DurationMslong

Attempt status values are stored as plain strings drawn from a constants class: success, failed and skipped.

Indexes

IndexColumnsUnique
IX_DeliveryAttempts_MessageIdmessageNo

There is no unique index on the message and attempt-number pair, so nothing structurally prevents two rows claiming the same attempt number for the same message.

Relationships

None declared. NotificationMessageId is a plain GUID with no foreign key, no navigation property and no cascade rule. Attempt rows are not deleted when a message is — and no code path deletes either.

Truncation

The error text is truncated in application code to the mapped maximum length before the row is added, so an oversized provider error is stored clipped rather than raising a length violation. This is one of only two places in the module where a value is defensively truncated; the other is the audit detail.

Timing

The recorder captures a start timestamp, measures elapsed time with a stopwatch, and computes the completion timestamp by adding the measured duration to the start value rather than reading the clock a second time. The stored duration and the stored timestamp difference are therefore consistent by construction.

Lifecycle

Append-only. Rows are never updated or deleted by any reviewed code path.

Classification

Implemented.

Requires confirmation

Whether a uniqueness guarantee on message and attempt number is intended requires confirmation.

See Also

Keywords

  • Notification database
  • Delivery Storage
  • Draft database documentation

Source References

  • microservices/src/notification-service/Infrastructure/NotificationDbContext.cs
  • microservices/src/notification-service/Domain/NotificationEntities.cs
  • microservices/src/notification-service/Application/NotificationDispatcher.cs
  • microservices/src/notification-service/Api/NotificationEndpoints.cs
  • microservices/src/notification-service/Infrastructure/Migrations/20260705113059_InitialNotificationSchema.cs

Revision Information

  • Status: Draft
  • Last reviewed: 2026-07-21
  • Review cycle: Quarterly