DBRaven
Failure Mode · resilience

Rate Limit Cascade

critical

Summary

When a downstream service begins rate limiting requests from an upstream service, the upstream's retry logic with insufficient backoff amplifies the request rate : exceeding the rate limit further and potentially pushing the rejection downstream to other upstream callers, producing a cascade of rate-limited retries across the call graph.

Description

Rate limiting is intended to protect a service from overload. When rate limiting begins, callers receive 429 Too Many Requests. Well-behaved callers back off. Poorly-behaved callers (or callers without explicit 429 handling) retry immediately or with minimal delay, increasing the request rate beyond the limit: the exact opposite of the intended behavior.

Cascade mechanics: 1. Service B begins rate limiting Service A (A is over quota or B is under load) 2. A's retry logic retries the 429 immediately or within 1 second 3. A now sends 2× requests (original + retry) to B 4. B rate-limits more requests; A retries more 5. A's request backlog grows; A begins to exhaust its own connection pool and

thread pool waiting for successful responses from B

6. A starts returning errors to its own callers (Service C) 7. C retries its requests to A, compounding A's load further

This pattern is particularly common when: - The retry library handles all non-2xx responses with immediate retry - No distinction is made between retryable (503, 502) and non-retryable (429) status codes - The Retry-After header from the 429 response is ignored

A rate-limit cascade can cause a brief transient rate limit event to become a prolonged partial outage across multiple services in the dependency graph.

Characteristics

Propagationfeedback loop
Time to detectImmediately visible in 429 response rate metrics if monitored. Without explicit 429 monitoring, the failure appears as elevated error rates and latency across services connected to the downstream: potentially attributed to other causes and taking minutes to diagnose.
Blast radiusThe rate limit cascade propagates upstream through the dependency graph: from B to A to C. In a deep call chain (C → A → B → D), a rate limit at D can propagate to C within seconds if each hop retries aggressively. At scale, the combined retry traffic from all upstreams can push a service far beyond its capacity, converting a rate limit event into a sustained overload.

Triggers

  • ·Downstream service begins rate limiting without the upstream implementing proper 429 handling
  • ·Traffic spike causes the upstream to exceed its downstream quota
  • ·Downstream reduces its rate limit quota without notifying upstreams
  • ·Retry middleware configured to retry all 5xx and 4xx responses uniformly

Detection Signals

error rate spikealert

Mitigation Strategies

Respect Retry-After header and implement 429 circuit breakingpreventscomplexity: low

When receiving a 429, extract the Retry-After header and wait the specified duration before retrying. If 429 responses persist, open a circuit breaker for that dependency rather than continuing to retry. The circuit breaker prevents the retry amplification loop.

Exponential backoff with jitter on all retriescomplexity: low

Configure retry logic with exponential backoff (delay doubles on each attempt) and random jitter (prevent synchronized retries from multiple instances). A starting backoff of 100ms × 2^attempt + rand(0, 100ms) prevents immediate re-requests. Maximum backoff should be 10–30 seconds.

Client-side token bucket for downstream callspreventscomplexity: medium

Implement a client-side rate limiter for calls to each downstream dependency. Set the limit to the downstream's documented quota. Requests above the limit are queued or rejected client-side before being sent: preventing rate limit events entirely by never exceeding the downstream's quota.

Recovery Steps

  1. 1.Identify the origin rate limit event in downstream metrics (first 429 responses)
  2. 2.Reduce upstream retry rate or apply circuit breaker to the 429-returning dependency
  3. 3.Check Retry-After headers in 429 responses and configure callers to honor them
  4. 4.Monitor 429 rate across all services in the dependency chain to identify propagation path
  5. 5.Post-incident: implement 429-specific handling in all retry middleware

Estimated recovery time: Stopping the retry amplification provides immediate relief (seconds). Root cause fix (implementing proper 429 handling) requires a code deployment (hours to days). Downstream capacity recovery (if the downstream was overloaded) takes minutes after upstream retry rate drops.

Affected Systems

Patterns

circuit breakerretry with backoffrate limitingapi gateway

Technologies

rediskafkapostgresql

Basis

Rate limit cascade mechanics are documented in AWS architecture best practices, Netflix Hystrix documentation, and Google SRE book chapter on handling overload; the retry-amplification pattern is a well-understood failure mode in distributed systems

Run This Failure

Blast radius analysis for this failure mode within each scenario that carries it.

Related Architecture Knowledge

Inbound: affects this entity

MitigatesPattern
rate limiting
Grounded

Rate limiting enforced at the API boundary prevents the retry amplification loop that causes rate limit cascades by ensuring callers never exceed the downstream quota in the first place.

Full relationship →

Used In Architecture Scenarios

API Gateway Platformhigh

Multi-Tenant SaaS

A multi-tenant API gateway providing authentication, distributed rate limiting, request routing, payload transformation, and per-tenant usage analytics for API publishers. The hot path: authentication check, rate limit evaluation, and routing decision: must complete in under 1ms using Redis-only data structures to avoid proxying latency dominating upstream service response time. PostgreSQL stores tenant configuration, subscription plans, and API key definitions. Kafka receives API usage events for downstream billing and analytics. Configuration changes (rate limit updates, routing rule edits) must propagate to all gateway replicas without restart.

Notification Delivery Platformmoderate

Event-Driven System

A multi-channel notification delivery architecture that accepts upstream business events (order placed, payment received, comment posted, threshold alert triggered) and routes them to per-channel delivery workers (push via FCM/APNs, email via SendGrid, SMS via Twilio, in-app via WebSocket). Kafka carries raw business events from upstream producers. RabbitMQ handles per-channel fan-out with separate exchanges and queues per delivery channel, isolating email queue backlog from push notification delivery. PostgreSQL provides durable notification state tracking (sent, failed, bounced, suppressed). Redis enforces per-user rate limiting (notification frequency caps to prevent fatigue) and stores deduplication tokens to prevent duplicate sends across retry attempts. The inbox pattern on the consumer side ensures idempotent delivery even when Kafka produces duplicate events.