Skip to content
AITroveRead. Build. Understand.
Make this comfortable

Spring outbox retry budget: park a poison event for inspection

Last updated: 1 Oct 20264 min read
tutorial
IntermediateBy AITrove Editorial

A retry budget moves repeatedly failed work into a state that automatic claims will no longer select.

Download Spring source kit

Stop at the boundary

The fixture uses a three-failure budget. Each claimed attempt fails with its current token. On the third failure, the row becomes DEAD; a later claim fails even after its due time. The stock balance remains unchanged because the consumer was never called. The row stays available for an operator to inspect rather than disappearing.

DEAD is only a local state in the model. It is not a configured broker dead-letter topic. A production operator workflow should expose the event ID, safe error category, attempt history, age, and a controlled replay action. Do not put raw credentials or personal payloads in those diagnostics.

Replay needs a rule

If a schema bug caused the failures, a code fix may make replay safe; if the consumer partially applied a side effect, replay requires a stable deduplication key. Decide whether the original event ID remains stable and whether the attempt counter resets. Record who released the event and why.

A single global attempt count may treat a brief outage like a poison payload. Pair attempts with a total elapsed budget and error classification when the actual transport exists. The retry lesson states what this local clock check covers.

Checked source

Java
status = nextFailureCount >= 3 ? "DEAD" : "PENDING";
// The claim query selects only PENDING rows.

Verification boundary

OutboxRelayFlowTest has seven local tests in the downloadable Spring source kit. The excerpt is shortened; the kit contains the complete test.

Costs and limits

The test checks one row and three sequential failures. It does not provide a dead-letter queue, retention policy, alerting, manual replay API, or broker failure classification.

Common Mistakes

  • Do not silently discard exhausted events.
  • Do not auto-replay a parked event with a new identity.
  • Do not leak sensitive payloads into error dashboards.

Read next

Spring outbox retries: due time, delay cap, and attempt accounting, Spring consumer idempotency: reserve an event ID with the stock mutation, Spring relay failure trace: inspect persisted state at each cut point, Spring receipt outbox command: record intent without claiming delivery.

Related boundary

Spring AMQP poison messages: reject, requeue and dead-letter are different decisions

spring
spring-boot
outbox
Storage details