Notification Deduplication Windows: Merge Noise Without Losing Distinct Events

Notification Deduplication Windows: Merge Noise Without Losing Distinct Events

Choose notification deduplication windows using event identity and business meaning, preserving separate actions while suppressing repeated transport deliveries.

SendDart Team

TL;DR

  • Treat deduplication as distinguishing duplicate deliveries from distinct events: suppress repeated notification attempts without erasing meaningful activity that happened close together.
  • Define a logical notification identity and enforce it atomically, using appropriate datastore concurrency controls and a deduplication window aligned with producer retry behavior and retention needs.
  • Validate the system with fixtures covering duplicate delivery, distinct same-content events, delayed retries and concurrent workers, and record suppression context so operators can explain decisions.

Separate duplicate delivery from similar activity

Two notification requests can represent the same business event delivered twice, or two distinct events that happen to look similar. A deduplication rule must distinguish those cases before it suppresses a message.

Start with the event identity supplied by the producer and the business object involved. Do not use the subject line or rendered body as the only key. Two legitimate receipts can have the same amount and wording while referring to different transactions.

The purpose is to remove repeated notification attempts, not erase meaningful activity because it occurred close together.

Define the unit that must happen once

Write the logical notification identity in terms of the application: event, recipient, notification type and relevant scope. The exact fields depend on the workflow.

For an illustrative document tool, a comment-created event sent to one subscribed reviewer may represent one notification decision. Delivering that event twice should not create two emails. A second comment on the same document is a different event even if the author writes the same words.

Preserve the distinction in the record so operators can explain why one request was suppressed while another similar-looking request was allowed.

Also decide whether a deliberate user-requested resend is the same notification attempt or a new authorized action. It should have a documented relationship to the original event and a controlled trigger, rather than bypassing every duplicate guard through an arbitrary new identifier.

Use a time window for a stated reason

A deduplication window determines how long the system remembers a completed or reserved notification identity. Choose it in relation to the producer's retry behavior, processing delays and the application's retention needs.

AWS documents that EventBridge can retry delivery under its configured policy. That is one example of why transport retries need deliberate handling; the actual producer's contract should guide your implementation.

Do not pick a very short window merely to reduce storage if legitimate retries can arrive later. Conversely, avoid storing unnecessary sensitive payloads indefinitely when a minimal identity record is sufficient.

Keep batching separate from deduplication

Combining several distinct comments into one digest is aggregation. Suppressing another attempt to notify about the same comment is deduplication. The two can work together, but they should have separate rules.

For the document example, three comments could produce one digest containing three items. A duplicated delivery of the second comment should not make the digest show four items. A fourth genuine comment should not disappear simply because it arrived inside the same window.

This distinction prevents a broad “ignore similar events for an hour” rule from becoming an accidental data-loss policy.

Reserve the decision safely under concurrency

Two workers can process the same event at nearly the same time. A check followed by an uncoordinated insert can allow both to conclude that no previous notification exists.

Use a concurrency mechanism appropriate to the datastore, such as a uniqueness constraint or atomic reservation around the logical identity. Define how the reservation moves through pending, submitted and resolved states.

The PostgreSQL transaction-isolation documentation provides context for concurrent operations. The important requirement is that the implementation enforces the intended identity rule, not merely that a helper function is named deduplicate.

Treat uncertain submission as a separate state

If a provider request times out, the application may not know whether the message was accepted. Do not automatically clear the reservation and resend without considering the provider's supported idempotency or reconciliation mechanisms.

Keep the business identity connected to the provider request identifier where available. Resolve uncertainty using the actual integration contract, and ensure that a retry does not create a new logical notification merely because it has a new local job ID.

A deduplication system should reduce accidental repetition while preserving evidence needed to recover from incomplete outcomes.

Test events that are deliberately close together

Use fixtures for the same event delivered twice, two distinct events with identical content, different recipients, a delayed retry and concurrent workers. Include an event arriving after the chosen memory window.

For the document tool, verify that a second real comment survives while the repeated transport delivery does not. Also check what happens if the first attempt failed before any provider submission; the recovery policy should not permanently suppress an event that still needs a valid notification.

These cases make the difference between preventing duplicates and simply dropping repeated-looking work.

Record the reason for suppression

Store enough context to say which logical identity already existed and what state it reached. Avoid logging full message bodies when identifiers and timestamps answer the operational question.

SendDart should receive the message the application has authorized after these decisions. The deduplication window is part of the application's event policy, not a substitute for understanding the delivery API. A clear identity and state model protects the recipient from duplicate noise while preserving genuinely separate events.

Related reading: Scheduled Email Delivery: Store the Time, Content and Cancellation State.

Related reading: Best Email API: Choose With a Production Acceptance Test.