Lesson 15 · Senior NATS practice

Replay, stale events, and idempotency boundaries

How to reason about replay safety, stale-message handling, dedup windows, and the real boundary between transport-level and application-level idempotency.

Your win: explain why replay is useful and dangerous at the same time, and how to talk about stale events, dedup, and idempotency without collapsing them into one idea.

Why replay sounds simpler than it is

Replay sounds like a pure reliability feature: messages are stored, so consumers can recover. That is true. But once a system can replay, it can also repeat, re-order the timing of effects, and wake up business logic that no longer wants the old event.

That is why senior engineers talk about replay safety, not just replay ability. The important question is not “can the bus re-deliver it?” The important question is “if the bus does re-deliver it, is the business outcome still correct?”

In plain English Plain English: replay helps recovery, but it only stays safe when old or repeated messages do not create the wrong side effects.
The replay rule Transport-level replay is only safe when the application can recognize, ignore, or safely re-apply repeated or outdated work.

Why dedup is only one part of the story

Publish-side dedup via Nats-Msg-Id helps suppress some repeated publishes within the dedup window. That is valuable, but it does not cover every repeated effect. Consumer redelivery, stale payload meaning, and business-level retries can still make the same logical work appear more than once.

So the strongest answer separates the layers. Dedup reduces one class of repeat. Idempotent handling and stale-event guards absorb the rest. If you blur those layers together, your answer sounds neat but not truthful.

Backend use case In this repo, Nats-Msg-Id plus app-level idempotency and stale guards like SkipMsgOlderThan work together — not interchangeably.
Common mistake Saying “dedup handles duplicates” without naming the boundary between publish dedup, redelivery, stale events, and business-level idempotency.
Read this next

Replay and dedup together

Use the JetStream model deep dive and the repo map together so the conceptual model stays tied to the real implementation.

JetStream model deep dive
Repo NATS map

Check yourself (from memory)

Q1. What is the strongest senior answer about replay safety?

Persistence helps recovery, but application semantics still decide whether recovery is safe.
Why isn’t Nats-Msg-Id dedup enough by itself?
recall, then click to reveal
Because publish dedup only suppresses some repeated publishes within its window. Consumer redelivery, stale semantics, and business-level retries still require application idempotency and replay judgment.
Want a “would replaying this event still be safe?” drill? Ask me.

Sources. JetStream model deep dive; repo NATS map.