Skip to content
AyoKoding

ADR-0006: Idempotency Cache for the Notification Worker

File path: services/notification-worker/docs/adr/0006-notification-worker-idempotency-cache.md -- colocated with the Notification Worker's own code (co-08). Continues the numbering already established by ADR-0001 (Scenario 9), ADR-0002/0003 (Scenario 10), ADR-0004 (Scenario 11), and ADR-0005 (Scenario 24) in the same Harborlight repository. Distills the accepted RFC (./rfc.md) into a single, durable decision record (co-06, ex-24's pattern).

Status: Accepted (2026-04-09)

Context

On 2026-04-02, a Notification Worker deployment restart triggered a Kafka consumer-group rebalance that replayed already-processed messages from each partition's last committed offset. The Notification Worker had no check for whether a given event had already been processed, so every replayed message produced a second, duplicate SMS or email to the customer. Full incident detail is in the postmortem; full options analysis is in the RFC.

Decision

The Notification Worker MUST check a Redis-backed idempotency cache, keyed on each event's event_id, before sending any customer notification. If event_id is already present in the cache, the worker MUST skip the send and log a duplicate_suppressed event instead. On a successful send, the worker MUST write event_id to the cache with a 48-hour TTL -- comfortably longer than any plausible consumer-group replay window observed to date.

Consequences

The Notification Worker gains a dependency on Redis (already run elsewhere in the Harborlight stack for the Carrier Adapter's rate-limit counters, so this adds load to existing infrastructure rather than introducing a new piece of infrastructure). A 48-hour TTL bounds the cache's memory footprint without risking a legitimate re-send being incorrectly suppressed (no shipment event is expected to replay more than 48 hours after its original processing). This decision does not address the consumer-group rebalance itself -- Kafka's at-least-once delivery guarantee is expected and unchanged; this ADR makes duplicate delivery safe to receive rather than attempting to prevent it at the source.

The full deliberation -- both options' pros and cons, the review log, and the TTL discussion -- lives in the RFC (./rfc.md), linked here for historical record but not required reading to understand the decision itself.

Last updated July 15, 2026

Command Palette

Search for a command to run...