Retry Loops & Backoff
MirApi Gateway’s retry engine automatically re-fires failed requests with exponential backoff and jitter, protecting your integrations from transient upstream failures — timeouts, 5xx errors, and connection drops.
How Retry Works
Section titled “How Retry Works”When an upstream request fails (connection error or 5xx response), the gateway waits and retries automatically. The delay follows this formula:
delay = base_delay × 2^attempt + random_jitter (up to 50% of delay)Maximum delay is capped at 10 seconds per attempt. If one of the retry attempts succeeds, the gateway returns the response to the client along with the diagnostic header X-Rescued: retry. Example with X-Retry-Delay: 200ms and X-Retry-Count: 4:
Initial attempt: → fails (e.g. 503)Retry 1: wait ~200ms + jitter → retryRetry 2: wait ~400ms + jitter → retryRetry 3: wait ~800ms + jitter → retryRetry 4: wait ~1600ms + jitter → retry or give upJitter distributes retry load across multiple clients so they don’t all hammer the upstream at the same time.
Required Headers
Section titled “Required Headers”| Header | Default | Description |
|---|---|---|
X-Retry-Count | 0 | Number of retry attempts (0 = disabled, max practical: 10) |
X-Retry-Delay | 100ms | Base delay for exponential backoff. Accepts Go durations: 100ms, 500ms, 1s |
X-Proxy-Timeout | 30s | Per-attempt timeout. Accepts Go durations: 1s, 5s, 30s. Maximum value: 30s. |
Use Cases
Section titled “Use Cases”1. Basic Retry for Transient Failures
Section titled “1. Basic Retry for Transient Failures”The most common use case — retry on 5xx or timeout:
curl -X POST https://proxy.mirapi.io/ \ -H "X-MirApi-Key: $MIRAPI_KEY" \ -H "X-Target-URL: https://api.stripe.com/v1/charges" \ -H "X-Identity-Key: Bearer sk_live_..." \ -H "X-Retry-Count: 3" \ -H "X-Retry-Delay: 500ms" \ -H "X-Proxy-Timeout: 5s" \ -H "Content-Type: application/json" \ -d '{"amount": 2000, "currency": "usd", "source": "tok_visa"}'2. Retry with Idempotency Key (Payments)
Section titled “2. Retry with Idempotency Key (Payments)”For payment endpoints, always pair retries with X-Proxy-Idempotency-Key to prevent duplicate charges:
curl -X POST https://proxy.mirapi.io/ \ -H "X-MirApi-Key: $MIRAPI_KEY" \ -H "X-Target-URL: https://api.stripe.com/v1/charges" \ -H "X-Identity-Key: Bearer sk_live_..." \ -H "X-Retry-Count: 3" \ -H "X-Retry-Delay: 1s" \ -H "X-Proxy-Timeout: 10s" \ -H "X-Proxy-Idempotency-Key: order_789_charge_attempt_1" \ -H "Content-Type: application/json" \ -d '{"amount": 9900, "currency": "usd", "source": "tok_visa"}'# If all 3 retries succeed at different points, only one charge is created# because Stripe deduplicates on the forwarded Idempotency-Key3. Retry + Smart Cache Fallback
Section titled “3. Retry + Smart Cache Fallback”If all retries fail, serve the last cached successful response:
curl https://proxy.mirapi.io/ \ -H "X-MirApi-Key: $MIRAPI_KEY" \ -H "X-Target-URL: https://api.exchangerate.host/latest" \ -H "X-Retry-Count: 3" \ -H "X-Retry-Delay: 200ms" \ -H "X-Smart-Cache: 300s"# If all 3 retries fail:# → serves last cached exchange rates from Redis# → response includes: X-Rescued: cache4. Retry + Failover URL
Section titled “4. Retry + Failover URL”After all primary retries fail, try a secondary endpoint:
curl -X POST https://proxy.mirapi.io/ \ -H "X-MirApi-Key: $MIRAPI_KEY" \ -H "X-Target-URL: https://primary-bank.com/api/charge" \ -H "X-Failover-URL: https://backup-bank.com/api/charge" \ -H "X-Retry-Count: 2" \ -H "X-Retry-Delay: 500ms" \ -H "X-Proxy-Timeout: 8s" \ -H "Content-Type: application/json" \ -d '{"amount": 5000, "currency": "usd"}'# primary fails × 2 → tries backup bank# response includes: X-Rescued: failover5. Fast-fail Retry for AI APIs
Section titled “5. Fast-fail Retry for AI APIs”For latency-sensitive AI requests, use tight timeouts to fail fast and retry quickly:
curl -X POST https://proxy.mirapi.io/ \ -H "X-MirApi-Key: $MIRAPI_KEY" \ -H "X-Target-URL: https://api.openai.com/v1/chat/completions" \ -H "X-Identity-Key: Bearer sk-proj-..." \ -H "X-Retry-Count: 2" \ -H "X-Retry-Delay: 100ms" \ -H "X-Proxy-Timeout: 8s" \ -H "Content-Type: application/json" \ -d '{"model": "gpt-4o", "messages": [{"role": "user", "content": "Hello"}]}'6. Async Retry (Long-running Jobs)
Section titled “6. Async Retry (Long-running Jobs)”Use X-Webhook-Callback for operations where the upstream may take minutes or hours to recover. The background worker continues retrying across restarts:
curl -X POST https://proxy.mirapi.io/ \ -H "X-MirApi-Key: $MIRAPI_KEY" \ -H "X-Target-URL: https://api.stripe.com/v1/charges" \ -H "X-Identity-Key: Bearer sk_live_..." \ -H "X-Webhook-Callback: https://your-app.com/webhook" \ -H "X-Proxy-Idempotency-Key: order_789_attempt_1" \ -H "X-Retry-Count: 5" \ -H "X-Retry-Delay: 2s" \ -d '{"amount": 9900, "currency": "usd"}'# Returns 202 immediately# Worker retries: 2s, 4s, 8s, 10s (capped), 10s+jitter# POSTs result to callback when Stripe respondsBackoff Timing Reference
Section titled “Backoff Timing Reference”| Attempt | X-Retry-Delay: 100ms | X-Retry-Delay: 500ms | X-Retry-Delay: 1s |
|---|---|---|---|
| 1 | ~100ms + jitter | ~500ms + jitter | ~1s + jitter |
| 2 | ~200ms + jitter | ~1000ms + jitter | ~2s + jitter |
| 3 | ~400ms + jitter | ~2000ms + jitter | ~4s + jitter |
| 4 | ~800ms + jitter | ~4000ms + jitter | ~8s + jitter |
| 5 | ~1600ms + jitter | ~8000ms + jitter | ~10s (capped) |
All delays are capped at 10 seconds maximum.