Skip to main content
Agent retry automatically re-runs failed LLM calls — across single-shot, streaming, tool-iteration and reflection turns — with jittered exponential backoff so transient rate limits, overloads, and network blips don’t break your agent. Retry is on by default (max_retries=3) on both the native OpenAI-client path and the LiteLLM path. Pass retry=False to opt out.
The user runs an agent; transient LLM failures retry automatically with jittered backoff — no retry= argument needed.
Upgrading from a version before this fix
  • If you never set retry=, your Agent now retries transient errors 3 times by default. In most cases this is transparent and desired.
  • If you relied on the old default (no retry) — a strict fail-fast pipeline or a local LLM endpoint — set retry=False on every affected Agent to restore the previous behaviour.
  • Existing retry=True, retry=dict, and retry=RetryBackoffConfig(...) uses are unchanged.
Only errors classified as retryable by LLMError.is_retryable are retried — non-retryable errors (authentication failures, invalid-request errors) still raise immediately. The ON_RETRY hook fires once per retry attempt, on both the native and LiteLLM paths.

Quick Start

1

Default — retries are already on

An Agent() with no retry= argument retries transient LLM failures automatically — on both the native and LiteLLM paths.The default policy: 3 retries, 5 s → 10 s → 20 s exponential schedule, capped at 120 s, with 50% additive jitter. retry=True is equivalent and explicit.
2

Disable with retry=False

retry=False turns retries off — the only way to opt out now that retries are on by default. Use it for strict fail-fast pipelines or local LLM servers (LM Studio / vLLM) that never emit Retry-After.
3

Tune with a dict (no extra import)

4

Full control with RetryBackoffConfig


How It Works

Which turn shapes retry?

retry= applies to every LLM call the agent makes, whether the model is being called for the first turn, a streaming turn, a tool-iteration turn, a reflection turn, or an async equivalent. If you can configure it, it retries. max_retries also caps the recursive retries the LLM path performs after context compression and after backing off on a transient error. These were previously fixed at 2; they now follow the configured policy, and fall back to 2 only when retry is disabled (retry=False). Since retry is on by default, the recursive bound follows max_retries=3 unless you override it.
Coverage across streaming and tool-iteration paths was made consistent in PraisonAI PR #2665. Before that release, streaming/tool-iter/reflection turns silently bypassed retry — a transient 429 on those paths surfaced raw. On current versions, retry= applies uniformly.
Behavioural change (fix for #3135): on versions after this fix, an Agent() created without a retry= argument uses RetryBackoffConfig() defaults on the native OpenAI-client path as well as the LiteLLM path. Prior to this fix, the native path silently skipped retries when retry= was not set. To restore the old “no retry” default, pass retry=False.
Behavioural change: RetryBackoffConfig.max_retries now also bounds the internal recursive retry loop. If you set max_retries=5, the compression / transient-backoff paths will now retry up to 5 times instead of the previous fixed 2.

Configuration Options

Omitting retry= is the same as retry=True — the default RetryBackoffConfig() applies.

RetryBackoffConfig Fields

Validation — the constructor raises ValueError if:
  • base_delay <= 0
  • max_delay < base_delay
  • jitter_ratio outside [0, 1]
  • max_retries < 0

Precedence & Defaults


Common Patterns

Rate-limit friendly long jobs

Strict mode — fail fast

Pass retry=False to disable retries entirely and surface transient errors immediately.
For a small-but-nonzero budget, keep retries on with a low max_retries:

Disable recursive retries entirely

Set max_retries=0 to disable the recursive compression / transient-backoff retries while keeping the retry policy configured.

Reproducible tests — disable jitter

Observe retries with a hook

The OnRetry hook receives:

Observability

The same backoff moment surfaces through two consumers — pick whichever fits your integration: Same signal, two consumers — hooks for programmatic control, stream events for live UIs and stream-json pipelines. When a run uses praisonai run --output stream-json, the stream event is emitted as a canonical run.retry NDJSON event, so a rate-limited run shows retrying in Ns (attempt k/N) instead of a silent-looking terminal.
Async agents (await agent.astart(...)) fire both the ON_RETRY hook and the RETRY stream event on the async retry loop. Async stream consumers should register via agent.stream_emitter.add_async_callback(async_fn); sync consumers keep using add_callback(sync_fn). Both are dispatched.

Best Practices

The defaults (base_delay=5.0, max_delay=120.0, jitter_ratio=0.5, max_retries=3) ship on every Agent and suit most OpenAI and Anthropic rate-limit patterns. Leave retry= off and only tune when you observe systematic timeouts or excessive waiting.
If your pipeline needs to surface transient LLM errors immediately — a health check, a local LM Studio / vLLM endpoint that never emits Retry-After, or a batch job with a hard wall-clock budget — pass retry=False explicitly. Omitting retry= no longer disables retries.
Setting jitter_ratio=0.0 creates a deterministic schedule that is useful for tests but dangerous in production. When many agents share the same API key and all retry at the same second, they hammer the endpoint simultaneously — exactly what jitter prevents. Keep jitter_ratio at 0.3 or higher in production.
A 120-second wait is acceptable for background batch jobs but not when a human is waiting for a response. For interactive agents, set max_delay to something like 20.0 or 30.0, and keep max_retries low (12).
The OnRetry hook is the right place to log metrics and send alerts. Retries are best-effort — if all attempts fail, the original LLMError propagates to your caller. Build your resilience strategy around catching that exception in your application code, not inside the hook.

Agent retry now applies to both the LiteLLM-backed agent loop and the native OpenAI-client path by default (max_retries=3). For the SDK-level Retry-After + backoff on the native OpenAIClient used by AutoAgents and direct get_openai_client() callers, see OpenAI Client Retries.

OpenAI Client Retries

SDK-level Retry-After + backoff for the native OpenAI client path.

Tool Retry Policy

Retry tool calls — a different surface from LLM call retry.

Structured LLM Errors

Which LLMError categories are classified as retryable.

Hook Events

The OnRetry event and all other lifecycle hooks.

Agent Retry Strategies

Strategy guidance for production retry patterns.