Retry Strategies¶
Both SDKs include built-in retry logic for transient failures. This guide explains how retries work and how to customize them.
Built-in Behavior¶
| Setting | Default | Description |
|---|---|---|
| Max retries | 3 | Total retry attempts after the initial request |
| Backoff | Exponential | 0.5s → 1s → 2s (Python), 500ms → 1s → 2s (TypeScript) |
| Retried errors | 5xx only | Server errors and connection/timeout failures |
| Not retried | 4xx | Client errors (auth, validation, rate limit) are never retried |
How It Works¶
Request 1 → 503 → wait 0.5s
Request 2 → 503 → wait 1.0s
Request 3 → 503 → wait 2.0s
Request 4 → 503 → raise ServerError
If any attempt succeeds, the response is returned immediately.
Customizing Retries¶
Disable Retries¶
Increase Retries¶
Custom Retry Logic¶
For more control, disable built-in retries and implement your own:
import time
from cloman import CloMan
from cloman._exceptions import ServerError, RateLimitError
client = CloMan(api_key="cloman_...", max_retries=0)
def decide_with_retry(context: str, max_attempts: int = 3) -> ...:
for attempt in range(max_attempts):
try:
return client.decide(context=context)
except ServerError:
if attempt < max_attempts - 1:
time.sleep(2 ** attempt)
continue
raise
except RateLimitError as e:
if e.retry_after and attempt < max_attempts - 1:
time.sleep(e.retry_after)
continue
raise
import { CloMan, ServerError, RateLimitError } from "@clomanai/sdk";
const client = new CloMan("cloman_...", { maxRetries: 0 });
async function decideWithRetry(context: string, maxAttempts = 3) {
for (let attempt = 0; attempt < maxAttempts; attempt++) {
try {
return await client.decide({ context });
} catch (error) {
if (error instanceof ServerError && attempt < maxAttempts - 1) {
await new Promise((r) => setTimeout(r, 2 ** attempt * 1000));
continue;
}
if (error instanceof RateLimitError && error.retryAfter && attempt < maxAttempts - 1) {
await new Promise((r) => setTimeout(r, error.retryAfter! * 1000));
continue;
}
throw error;
}
}
}
What Gets Retried¶
| Scenario | Retried? | Reason |
|---|---|---|
| 500 Internal Server Error | Yes | Transient server issue |
| 502 Bad Gateway | Yes | Upstream service issue |
| 503 Service Unavailable | Yes | Temporary overload |
| Connection refused | Yes | Server might be restarting |
| Request timeout | Yes | Network hiccup |
| 401 Authentication Error | No | Invalid key won't become valid |
| 403 Authorization Error | No | Missing permissions won't appear |
| 404 Not Found | No | Resource won't appear |
| 422 Validation Error | No | Bad input won't fix itself |
| 429 Rate Limit | No | Handled separately via retry_after |