Exponential backoff retry logic for transient API errors.
Wraps an LLM call with automatic retries for rate limits (429), server errors (500, 502, 503, 529), network timeouts, and connection resets. Non-retryable errors (400, 401, 403) fail immediately.
Uses exponential backoff with jitter: base delays of 1s, 2s, 4s, 8s
plus random jitter up to 50% of the delay. Respects Retry-After
headers when present.
Summary
Functions
Returns true if the given error reason is retryable.
Calls the given function with retry logic on transient errors.
Types
@type opts() :: [ max_retries: non_neg_integer(), base_delay_ms: pos_integer(), on_retry: (non_neg_integer(), non_neg_integer(), String.t() -> :ok) | nil ]
Options for retry behavior.
Functions
Returns true if the given error reason is retryable.
Calls the given function with retry logic on transient errors.
The function should return {:ok, result} or {:error, reason}.
Options:
:max_retries- maximum number of retry attempts (default: 3):base_delay_ms- initial backoff delay in milliseconds (default: 1000):on_retry- callback(attempt, delay_ms, reason)called before each retry
Examples
Retry.with_retry(fn -> api_call() end, max_retries: 3)