Spring Retry
Retry abstraction for Spring applications — provides declarative (@Retryable) and programmatic (RetryTemplate) retry with configurable backoff policies. Spring Retry features: @Retryable(retryFor=IOException.class, maxAttempts=3, backoff=@Backoff(delay=1000, multiplier=2)) annotation, @Recover fallback method, RetryTemplate with ExponentialBackOffPolicy, SimpleRetryPolicy, CircuitBreakerRetryPolicy, stateful retry for message-driven recovery, RetryContext for cross-attempt state, and @EnableRetry on configuration class. Used in Spring Batch, Spring AMQP, and Spring Kafka internally. Lighter weight than Resilience4j for pure retry use cases.
Score Breakdown
⚙ Agent Friendliness
🔒 Security
Retry amplifies agent API calls — exponential backoff prevents agent thundering herd on downstream services during outages. Ensure retried agent operations are idempotent to prevent double-charging, duplicate sends, or duplicate agent task execution. Log retry attempts for agent audit trails.
⚡ Reliability
Best When
Your Spring agent service makes external API calls (LLM APIs, partner APIs) that transiently fail and need simple retry with exponential backoff — Spring Retry's @Retryable annotation eliminates boilerplate retry loops.
Avoid When
You need circuit breaker, bulkhead, or rate limiting (use Resilience4j), or you're using Spring Kafka where built-in retry is more appropriate.
Use Cases
- • Agent LLM API retry on transient failure — @Retryable(retryFor = {RateLimitException.class, IOException.class}, maxAttempts = 3, backoff = @Backoff(delay = 1000, multiplier = 2.0)) on agent LLM call method; automatically retries with 1s, 2s delays before propagating exception
- • @Recover fallback for agent calls — @Recover public AgentResponse fallback(RateLimitException e, AgentRequest req) { return AgentResponse.rateLimitedResponse() } invoked after all @Retryable attempts exhausted; agent graceful degradation without try/catch in business logic
- • RetryTemplate for programmatic agent retry — RetryTemplate template = RetryTemplate.builder().maxAttempts(5).exponentialBackoff(500, 2.0, 10000).retryOn(TransientException.class).build(); template.execute(ctx -> callExternalAgentApi()) with explicit retry context
- • Agent batch processing retry — Spring Batch uses Spring Retry internally; agent job step configured with retryLimit and list of retryable exceptions; failed agent task item retried configured times before skip or job failure
- • Circuit breaker retry combination — CircuitBreakerRetryPolicy wraps SimpleRetryPolicy; agent service opens circuit after threshold failures; subsequent calls fail fast without retry until circuit closes; lighter alternative to Resilience4j circuit breaker for Spring-native agent services
Not For
- • Comprehensive resilience patterns — Spring Retry focuses on retry/backoff; for bulkhead, rate limiting, and time limiter use Resilience4j
- • Non-Spring Java applications — Spring Retry requires Spring AOP for @Retryable annotation support; for plain Java retry use Failsafe or Guava Retryer
- • Kafka consumer retry — Spring Kafka has its own DefaultErrorHandler with retry; using Spring Retry @Retryable on @KafkaListener conflicts with Spring Kafka's offset management; use Spring Kafka's built-in retry configuration for agent message consumers
Interface
Authentication
No auth — retry abstraction library. Authentication for retried calls handled by the calling agent service.
Pricing
Spring Retry is Apache 2.0 licensed, maintained by the Spring team. Free for all use.
Agent Metadata
Known Gotchas
- ⚠ @EnableRetry required on configuration class — @Retryable annotations silently do nothing without @EnableRetry on @Configuration class or Spring Boot application; agent services adding @Retryable without @EnableRetry have zero retry behavior; add @EnableRetry to Spring Boot main class or dedicated RetryConfig @Configuration
- ⚠ @Retryable only works on Spring beans called externally — Spring Retry uses AOP proxy; calling @Retryable method from within same class bypasses proxy; agent service method calling another @Retryable method on 'this' reference skips retry; inject self or extract to separate @Service bean for agent internal retry
- ⚠ noRetryFor vs retryFor mutually exclusive patterns — @Retryable with no retryFor retries on all exceptions; specifying retryFor={IOException.class} retries ONLY those exceptions; noRetryFor={RuntimeException.class} retries all EXCEPT those; agent code specifying retryFor={Exception.class} catches all including unchecked exceptions unexpectedly
- ⚠ @Recover method signature must match @Retryable — @Recover method must accept same parameters as @Retryable method plus exception as first parameter; return type must match; mismatched @Recover signatures cause ExhaustedRetryException instead of fallback invocation for agent degraded response
- ⚠ Stateful retry requires unique RetryState — stateful retry (for Spring Batch/AMQP) needs RetryState key matching item; stateless @Retryable is default and appropriate for agent API calls; mixing stateful and stateless retry for agent message processing causes unexpected retry counts
- ⚠ Backoff maxDelay ceiling essential for agent SLAs — @Backoff(delay=1000, multiplier=2) without maxDelay caps exponentially: 1s, 2s, 4s, 8s... with maxAttempts=10 means last retry at 512s delay; always set maxDelay=30000 (or appropriate agent SLA ceiling) to prevent multi-minute backoffs in agent production services
Alternatives
Full Evaluation Report
Detailed scoring breakdown, competitive positioning, security analysis, and improvement recommendations for Spring Retry.
Scores are editorial opinions as of 2026-03-06.