BackendBench
Coffee

Unravel › Java concepts › Cloud and operations

I/O and data

Retry and circuit breaker

Remote calls fail for short moments.

Learn these first

At a glance

Mental model

If a shop door is stuck you try the handle again once or twice (retry).

What happens, in order
  1. 1Retry: @Retryable(maxAttempts = 3, backoff = @Backoff(delay = 500, multiplier = 2)) repeats the call after 0.5 s, then 1 s, before the exception reaches the caller@Recover supplies a fallback after the last attempt.
  2. 2Circuit breaker: it counts recent failuresClosed means calls go through; when the failure rate passes a threshold it opens and calls fail immediately; after a wait it goes half-open, lets a few calls through and closes again if they succeed.
  3. 3Resilience4j offers @Retry, @CircuitBreaker, @RateLimiter, @Bulkhead and @TimeLimiter, usually with a fallbackMethod for what to return while the breaker is open
  4. 4Both are applied through proxies, so they only work on calls from another bean
Remember
Watch out
Retrying non-idempotent operationsNo backoff or jitter, so retries arrive in a synchronized waveRetrying calls that have no timeoutA fallback that hides failures completelyCalling the annotated method from within the same class
Example (highlighted lines explain it)
@Retryable(retryFor = ResourceAccessException.class, maxAttempts = 3,           backoff = @Backoff(delay = 500, multiplier = 2))public Quote fetchQuote(String symbol) {    return restClient.get().uri("/quotes/{s}", symbol).retrieve().body(Quote.class);}@Recoverpublic Quote fallback(ResourceAccessException e, String symbol) {    return Quote.unavailable(symbol);}
  1. line 1 uses Retryable, the core of Retry and circuit breaker
  2. line 2 uses Backoff, the core of Retry and circuit breaker
  3. line 7 uses Recover, the core of Retry and circuit breaker
Read the full explanation (about 2 min)

Remote calls fail for short moments. Retry tries again after a pause; a circuit breaker stops calling a dependency that keeps failing, so a sick service is not hammered and your own threads are not all stuck waiting for it.

A mental model

If a shop door is stuck you try the handle again once or twice (retry). If it is clearly locked, you stop trying for a while and check back later (circuit breaker), instead of standing there rattling it.

How it works

Retry: @Retryable(maxAttempts = 3, backoff = @Backoff(delay = 500, multiplier = 2)) repeats the call after 0.5 s, then 1 s, before the exception reaches the caller. @Recover supplies a fallback after the last attempt.

Circuit breaker: it counts recent failures. Closed means calls go through; when the failure rate passes a threshold it opens and calls fail immediately; after a wait it goes half-open, lets a few calls through and closes again if they succeed.

Resilience4j offers @Retry, @CircuitBreaker, @RateLimiter, @Bulkhead and @TimeLimiter, usually with a fallbackMethod for what to return while the breaker is open.

Both are applied through proxies, so they only work on calls from another bean.

Going deeper

Only retry operations that are safe to repeat (idempotent): reading data, or writing with an idempotency key. Retrying "charge the card" can charge twice.

Retries multiply load: three attempts from each of 100 callers means 300 calls against a service that is already struggling. Use exponential backoff with random jitter, and a small attempt limit.

Always combine retries with timeouts. A retry around a call that can hang forever just hangs three times as long.

A fallback that silently returns an empty or default value hides the outage. Log it, count it in a metric and decide whether the caller should see an error instead.

Under the hood

The annotations are handled by an aspect that wraps the invocation in a retry loop or a state machine. The circuit breaker keeps a sliding window (by count or by time) of outcomes in memory per named breaker, so each instance of your application has its own state.

Common mistakes

  • Retrying non-idempotent operations.
  • No backoff or jitter, so retries arrive in a synchronized wave.
  • Retrying calls that have no timeout.
  • A fallback that hides failures completely.
  • Calling the annotated method from within the same class.

How Unravel recognises it

When you paste code, Unravel looks for these signs of retry and circuit breaker. Spotting them yourself is a good habit when you read unfamiliar code:

Part of a learning path

Related concepts

Frequently asked questions

What is Retry and circuit breaker?

Remote calls fail for short moments. Retry tries again after a pause; a circuit breaker stops calling a dependency that keeps failing, so a sick service is not hammered and your own threads are not all stuck waiting for it.

What are the most common mistakes with Retry and circuit breaker?

Retrying non-idempotent operations. No backoff or jitter, so retries arrive in a synchronized wave. Retrying calls that have no timeout. A fallback that hides failures completely. Calling the annotated method from within the same class.

How can I see Retry and circuit breaker in real code?

Paste your own Java into Unravel and it will point out where retry and circuit breaker appears, explain how it works at the detail level you choose, and draw the flow of the code around it.