> ## Documentation Index
> Fetch the complete documentation index at: https://splinter.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Retry Strategy

> Retry failed calls with exponential backoff

Transient failures happen. Retry strategies handle them gracefully with exponential backoff and jitter.

## Basic Usage

```python theme={null}
from splinter.control import RetryStrategy, RetryConfig

strategy = RetryStrategy(RetryConfig(
    max_attempts=3,
    initial_delay=1.0,
    max_delay=30.0,
    backoff_multiplier=2.0,
))

# Retry automatically
result = await strategy.execute(flaky_function, arg1, arg2)
```

## Retry Timing

With default config:

```
Attempt 1: Immediate
Attempt 2: Wait 1s
Attempt 3: Wait 2s
Attempt 4: Wait 4s (capped at max_delay)
```

## Retry Modes

```python theme={null}
from splinter.control import RetryMode

# Basic: Retry on any exception
RetryConfig(mode=RetryMode.BASIC)

# Selective: Only retry specific exceptions
RetryConfig(
    mode=RetryMode.SELECTIVE,
    retry_on=[ConnectionError, TimeoutError],
)

# Fail-closed: Stop on first failure (for critical operations)
RetryConfig(mode=RetryMode.FAIL_CLOSED)
```

## Jitter

Add randomness to prevent thundering herd:

```python theme={null}
RetryConfig(
    initial_delay=1.0,
    jitter=0.5,  # ±0.5s random
)
# Delay will be 0.5s to 1.5s
```

## Custom Retry Conditions

```python theme={null}
def should_retry(exception, attempt):
    # Don't retry client errors
    if isinstance(exception, ClientError):
        return False
    # Retry server errors up to 5 times
    if isinstance(exception, ServerError):
        return attempt < 5
    return True

strategy = RetryStrategy(RetryConfig(
    retry_condition=should_retry,
))
```

## Callbacks

```python theme={null}
def on_retry(attempt, exception, delay):
    print(f"Attempt {attempt} failed: {exception}")
    print(f"Retrying in {delay:.1f}s")

strategy = RetryStrategy(RetryConfig(
    max_attempts=3,
    on_retry=on_retry,
))
```

## Circuit Breaker Integration

Combine with circuit breakers:

```python theme={null}
from splinter.control import RetryStrategy, CircuitBreaker

breaker = CircuitBreaker(breaker_id="api", failure_threshold=5)

async def call_with_protection():
    breaker.check()  # Raises if circuit open
    try:
        result = await strategy.execute(api_call)
        breaker.record_success()
        return result
    except Exception as e:
        breaker.record_failure()
        raise
```

## Best Practices

<AccordionGroup>
  <Accordion title="Always use backoff">
    Immediate retries can overwhelm failing services.
  </Accordion>

  <Accordion title="Set reasonable max_attempts">
    3-5 is usually enough. More than that, the service is probably down.
  </Accordion>

  <Accordion title="Add jitter">
    Prevents all clients from retrying at the same time.
  </Accordion>

  <Accordion title="Don't retry non-transient errors">
    400 errors won't succeed on retry. Only retry 5xx and network errors.
  </Accordion>
</AccordionGroup>
