B2B Integrations के लिए Retry/Backoff Patterns 2026: Polly, axios-retry, tenacity
Retry का मतलब "while loop के अंदर try/catch wrap" नहीं है। सही strategy error class, upstream service की expected SLA, और recovery के दौरान current load पर depend करती है। यह article B2B integrations में retry patterns का practical reference है, production code samples के साथ।
1. Base formula: exponential + jitter
function delay(attempt: number, baseMs = 500, capMs = 30000): number {
const exp = Math.min(baseMs * Math.pow(2, attempt), capMs);
const jitter = Math.random() * exp * 0.5; // ±50%
return exp / 2 + jitter; // "full jitter" AWS-style
}
// attempt 0: 250–750ms
// attempt 1: 500–1500ms
// attempt 2: 1000–3000ms
// attempt 5: 8000–24000ms
"Full jitter" (ऊपर वाला) AWS-recommended है और "equal jitter" से recovery पर peak load ज़्यादा कम करता है।
2. कब retry करें और कब नहीं
| HTTP status | Retryable? | Comment |
|---|---|---|
| 5xx | Yes | Server-side transient |
| 429 | Yes | Retry-After header respect करें |
| 408 | Yes | Client timeout |
| 4xx (बाकी) | No | Permanent client error |
| Network error | Yes | DNS, conn reset, TLS |
| Timeout | Yes | Careful — request complete हो भी सकता है |
POST timeouts के लिए special case: सिर्फ idempotency key के साथ retry करें, वरना duplicates बनेंगे।
3. axios-retry (Node.js)
import axios from 'axios';
import axiosRetry from 'axios-retry';
const client = axios.create({ baseURL: 'https://api.foxreload.com', timeout: 30000 });
axiosRetry(client, {
retries: 5,
retryDelay: (count) => axiosRetry.exponentialDelay(count) + Math.random() * 1000,
retryCondition: (err) => {
if (!err.response) return true; // network
const s = err.response.status;
return s >= 500 || s === 429 || s === 408;
},
shouldResetTimeout: true,
});
shouldResetTimeout: true essential है — इसके बिना एक 30s timeout पूरा retry budget खा जाता है।
4. tenacity (Python)
from tenacity import retry, stop_after_attempt, wait_exponential_jitter, retry_if_exception_type
import httpx
@retry(
stop=stop_after_attempt(6),
wait=wait_exponential_jitter(initial=0.5, max=30, jitter=2),
retry=retry_if_exception_type((httpx.TransportError, httpx.HTTPStatusError)),
reraise=True,
)
def create_order(payload, idem_key):
r = httpx.post('https://api.foxreload.com/v1/orders',
json=payload,
headers={'Idempotency-Key': idem_key},
timeout=30)
if r.status_code >= 500 or r.status_code == 429:
r.raise_for_status()
return r.json()
5. Polly (C#/.NET)
var policy = Policy
.HandleResult<HttpResponseMessage>(r => (int)r.StatusCode >= 500 || (int)r.StatusCode == 429)
.Or<HttpRequestException>()
.WaitAndRetryAsync(5, attempt =>
TimeSpan.FromMilliseconds(500 * Math.Pow(2, attempt)
+ Random.Shared.Next(0, 500)));
var circuit = Policy
.HandleResult<HttpResponseMessage>(r => (int)r.StatusCode >= 500)
.CircuitBreakerAsync(5, TimeSpan.FromSeconds(60));
var combined = Policy.WrapAsync(circuit, policy);
var resp = await combined.ExecuteAsync(() => client.PostAsync("/v1/orders", body));
6. Circuit breaker — जब retries काम नहीं करते
अगर upstream 30 seconds तक 50%+ fail करे, breaker open करें और तुरंत fail करें:
import CircuitBreaker from 'opossum';
const breaker = new CircuitBreaker(callFoxreload, {
errorThresholdPercentage: 50,
resetTimeout: 60_000,
rollingCountTimeout: 30_000,
});
breaker.fallback(() => ({ fromCache: true }));
यह outage के दौरान downstream को retry avalanche से बचाता है।
CTA
FoxReload API 429 पर Retry-After return करता है और सारे endpoints पर HTTP/2 use करता है। Full retry recommendations access request करने के बाद onboarding doc में हैं।
