Retry Strategies¶
Model providers occasionally encounter errors such as rate limits, service unavailability, or network timeouts. By default, the agent retries ModelThrottledException failures automatically with exponential backoff and the Angent.retry_strategy parameter lets you customize this behavior.
Default Behavior¶
Without configuration, agents retry ModelThrottledException up to 5 times (6 total attempts) with exponential backoff starting at 4 seconds:
Attempt 1: fails → wait 4s
Attempt 2: fails → wait 8s
Attempt 3: fails → wait 16s
Attempt 4: fails → wait 32s
Attempt 5: fails → wait 64s
Attempt 6: fails → exception raised
Customizing Retry Behavior¶
Use ModelRetryStrategy to adjust the retry parameters:
from strands import Agent, ModelRetryStrategy
agent = Agent(
retry_strategy=ModelRetryStrategy(
max_attempts=3, # Total attempts (including first try)
initial_delay=2, # Seconds before first retry
max_delay=60 # Cap on backoff delay
)
)
// Not supported in TypeScript
Parameters¶
| Parameter | Type | Default | Description |
|---|---|---|---|
max_attempts |
int |
6 |
Total number of attempts including the initial call. Set to 1 to disable retries. |
initial_delay |
float |
4 |
Seconds to wait before the first retry. Subsequent retries double this value. |
max_delay |
float |
128 |
Maximum seconds to wait between retries. Caps the exponential growth. |
Disabling Retries¶
To disable automatic retries entirely:
from strands import Agent, ModelRetryStrategy
agent = Agent(
retry_strategy=None
)
// Not supported in TypeScript
When Retries Occur¶
ModelRetryStrategy handles ModelThrottledException, which model providers raise for rate-limiting. Other exceptions propagate immediately without retry.
Custom Retry Logic¶
Built in retry constructs like ModelRetryStrategy are useful for customizing model rate-limiting behavior, but for more fine-grained control - like validating model responses or handling additional exception types - use a hook instead. The AfterModelCallEvent fires after each model call and lets you set event.retry = True to trigger another attempt:
import asyncio
from strands import Agent
from strands.hooks import HookProvider, HookRegistry, AfterModelCallEvent
class CustomRetry(HookProvider):
def __init__(self, max_retries: int = 3, delay: float = 2.0):
self.max_retries = max_retries
self.delay = delay
self.attempts = 0
def register_hooks(self, registry: HookRegistry) -> None:
registry.add_callback(AfterModelCallEvent, self.maybe_retry)
async def maybe_retry(self, event: AfterModelCallEvent) -> None:
if event.exception and self.attempts < self.max_retries:
self.attempts += 1
await asyncio.sleep(self.delay)
event.retry = True
agent = Agent(hooks=[CustomRetry()])
// Not supported in TypeScript
Unlike ModelRetryStrategy, hooks don't automatically introduce delays between retries. The example above uses asyncio.sleep to add a 2-second delay before each retry.
See Hooks for more examples.