Skip to main content
The @RetryPolicy annotation enables automatic retry with exponential backoff for failed handler invocations. When placed on a class alongside @ChangeStream, the framework retries the handler up to maxAttempts times with increasing delays between attempts.

Attributes

AttributeTypeDefaultDescription
maxAttemptsint3Maximum number of attempts (including the initial one)
initialDelayString"500ms"Delay before the first retry. Supports "500ms", "1s", "1m" format
maxDelayString"30s"Maximum delay cap
multiplierdouble2.0Multiplier applied to the delay between each retry
retryOnClass<? extends Throwable>[]{}Exception types that trigger a retry. Empty = all exceptions (except noRetryOn)
noRetryOnClass<? extends Throwable>[]See belowException types that should never trigger a retry
jitterbooleantrueAdds random variation (±20%) to the computed delay
maxAttempts includes the initial invocation. So maxAttempts = 3 means 1 initial attempt + 2 retries.

noRetryOn Defaults

By default, the following exceptions skip retry entirely — they are considered programming errors that retrying won’t fix:
  • IllegalArgumentException
  • NullPointerException
  • ClassCastException
noRetryOn always takes precedence over retryOn.

Backoff Algorithm

The delay between retries is computed using exponential backoff with an optional jitter:
baseDelay   = initialDelay × (multiplier ^ (attemptNumber - 1))
cappedDelay = min(baseDelay, maxDelay)

if jitter = true:
    finalDelay = cappedDelay × random(0.8, 1.2)    // ±20%
else:
    finalDelay = cappedDelay
For the defaults (initialDelay = "500ms", multiplier = 2.0, maxDelay = "30s", jitter = false), the delays are:
AttemptDelay
1 (initial)
2 (1st retry)500ms
3 (2nd retry)1s
42s
54s
68s
716s
8+30s (capped)

YAML Configuration

Global retry defaults can be set in application.yml. Annotation attributes override these values per stream.
flowwarden:
  stream:
    retry:
      max-attempts: 3
      initial-delay: 1s
      multiplier: 2.0
      max-delay: 30s

See Also

Retry & DLQ Guide

Understand retry flows, exception filtering, tracking attempts, and best practices

@DeadLetterQueue

Store events that exhaust all retries for later reprocessing

@Checkpoint

Resume token persistence for reliable stream recovery

ChangeStreamContext

Runtime context including attempt number, event ID, and more