← CodeClarityLab Home
Browse by Category
+ added · updated 7d
← Back to glossary

Retry Pattern with Exponential Backoff

architecture PHP 5.0+ Intermediate

Also Known As

retry logic exponential backoff retry with backoff

TL;DR

Automatically retrying failed operations with increasing delays — preventing thundering herd and handling transient failures gracefully.

Explanation

Transient failures (network blips, rate limit 429s, database deadlocks) are often self-resolving. The Retry pattern retries the operation automatically, but naive immediate retries can overwhelm a struggling service. Exponential backoff doubles the wait on each attempt (1s, 2s, 4s, 8s...); jitter adds randomness to spread retries from many clients (prevents thundering herd). Best practices: cap maximum retries (3–5), cap maximum delay (30–60s), only retry idempotent operations (GET, PUT — not POST without idempotency keys), use a circuit breaker to stop retrying when the service is clearly down. Guzzle's retry middleware and symfony/http-client both support retry configuration. Log every retry with the delay and reason.

Diagram

flowchart TD
    REQ[Send Request] --> TRY{Success?}
    TRY -->|Yes| DONE[Done]
    TRY -->|No| CHECK{Retryable
error?}
    CHECK -->|No - 400 400 auth| FAIL[Fail immediately]
    CHECK -->|Yes - 500 429 timeout| WAIT[Wait with<br/>exponential backoff<br/>1s -> 2s -> 4s -> 8s]
    WAIT --> ATTEMPTS{Max attempts
reached?}
    ATTEMPTS -->|No| REQ
    ATTEMPTS -->|Yes| GIVEUP[Give up<br/>alert / dead letter]
style DONE fill:#238636,color:#fff
style FAIL fill:#f85149,color:#fff
style GIVEUP fill:#f85149,color:#fff
style WAIT fill:#d29922,color:#fff

Common Misconception

Retrying immediately after a failure is as effective as backoff. Immediate retries hammer a struggling dependency and worsen cascading failures. Exponential backoff with jitter spreads retry load, and idempotency checks ensure retried operations do not create duplicate side effects.

Why It Matters

Retrying transient failures (network blips, rate limits, temporary outages) automatically improves resilience — but retrying without backoff and jitter amplifies load on an already struggling service.

Common Mistakes

  • Retrying non-idempotent operations without checking — retrying a payment charge double-charges the customer.
  • Constant retry interval without exponential backoff — hammers a recovering service at full rate.
  • No jitter — all clients retry at the same time, creating a thundering herd.
  • No maximum retry limit — infinite retries hold resources and can cause cascading failures.

Code Examples

✗ Vulnerable
// Retry without backoff or limit — thundering herd:
for ($i = 0; $i < 10; $i++) {
    try {
        return $this->http->post('/payments', $data);
    } catch (Exception $e) {
        sleep(1); // Same interval every time — all clients retry simultaneously
    }
}
// Fix: sleep(2 ** $i + random_int(0, 1000) / 1000) — exponential backoff with jitter
✓ Fixed
// Guzzle retry middleware
$handler = HandlerStack::create();
$handler->push(Middleware::retry(
    fn($retries, $req, $res) => $retries < 3 && ($res?->getStatusCode() === 429),
    fn($retries) => (int)(1000 * 2 ** $retries) // exponential ms delay
));

Added 15 Mar 2026
Edited 19 Apr 2026
Views 33
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 1 ping S 0 pings S 1 ping M 1 ping T 0 pings W 1 ping T 0 pings F 2 pings S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 1 ping F 2 pings S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 1 ping S
No pings yesterday
Amazonbot 8 Perplexity 5 ChatGPT 5 Unknown AI 3 Google 2 Ahrefs 1 Qwen 1
crawler 25
DEV INTEL Tools & Severity
🟡 Medium ⚙ Fix effort: Medium
⚡ Quick Fix
Use exponential backoff with jitter for retries — not fixed delay, not infinite retries; always set a maximum retry count and a dead-letter destination
📦 Applies To
PHP 5.0+ web queue-worker laravel symfony
🔗 Prerequisites
🔍 Detection Hints
try/catch that immediately retries in a tight loop without backoff; queue job with $tries=0 unlimited retries
Auto-detectable: ✗ No semgrep
⚠ Related Problems
🤖 AI Agent
Confidence: Medium False Positives: Medium ✗ Manual fix Fix: Medium Context: Function Tests: Update

✓ schema.org compliant