AWS Builder Center
Managing Traffic Spikes with Amazon Bedrock: Why Traditional Retry Patterns Fail (Part 1)

Managing Traffic Spikes with Amazon Bedrock: Why Traditional Retry Patterns Fail (Part 1)

This article explains why traditional retry patterns fail during traffic spikes on Amazon Bedrock, causing retry amplification and quota waste, and advocates replacing reactive retries with proactive rate limiting using semaphores for concurrency control and token buckets to enforce sustainable request rates—ensuring stability without failures.

Written by Jean Malha Senior Specialist Solutions Architect - Agentic AI, Ryan Sachs Solutions Architect - Startups, Pavel Novichkov Senior Solutions Architect - Startups
Cover Image generated with  Amazon Nova 2 Omni .
Amazon Bedrock offers three deployment options for foundation model inference: on-demand for pay-per-use flexibility, provisioned throughput for guaranteed capacity, and batch inference for cost-effective bulk processing. Each comes with built-in rate limiting and quota management to ensure fair resource allocation across customers. However, when applications experience traffic spikes, the standard distributed systems playbook—retry with exponential backoff—becomes counterproductive.
Here's why:

The Bedrock Rate Limiting Reality

Bedrock protects both your costs and system stability through several mechanisms:
  • Requests per minute (RPM) limits on model invocations
  • Tokens per minute (TPM) limits on input/output processing
  • Concurrent request limits to prevent resource exhaustion (for Batch Inference)
  • Throttling responses (HTTP 429) when limits are exceeded
While Bedrock doesn't charge you for throttled requests, your application still suffers from the cascading effects of retries during peak traffic.

Why Exponential Backoff Fails at Scale

Traditional retry patterns work well for transient failures in stateless services, but foundation model workloads have unique characteristics that make retries toxic:
Problem 1: Retry Amplification
When 1000 requests hit your 600 RPM limit, 400 requests get throttled. Each retry attempt (even after backoff) adds to the request volume, creating a feedback loop where failures generate more load, not less.
Problem 2: Quota Waste in Multi-Service Architectures
In agentic frameworks like Amazon Bedrock Agents or custom LangGraph implementations, a single user request often triggers multiple model calls. Failed calls in one service component can trigger retries that consume quota needed by other components, creating cross-service resource starvation.
Problem 3: Unpredictable Performance
Exponential backoff spreads retries randomly over time but doesn't reduce total request volume. Your application alternates between periods of success and systematic failure, making performance unpredictable for end users.
In cases where you need sequential execution of multiple FM calls and you have full control over the applications doing the calls to the api, the solution isn't better retries—it's eliminating the need for retries entirely through proactive rate limiting.

Understanding Rate Limiting: Semaphores and Token Buckets

Before diving into the solution, let's understand two complementary mechanisms for controlling resource access:

Semaphores: Controlling Concurrency

A semaphore limits concurrent operations—like a bouncer at a nightclub with fixed capacity:
  • Maintains a counter (e.g., "600 people can be inside")
  • Counter decrements when someone enters, increments when they leave
  • New arrivals wait if counter reaches zero
For Bedrock calls, a semaphore prevents overwhelming your system with too many simultaneous requests. If your application can handle 600 concurrent API calls before exhausting connection pools, a semaphore with capacity 600 ensures you never exceed that limit.
What semaphores DON'T do: They don't control request rate over time. You could still send 1000 requests per second (each completing quickly), violating Bedrock's rate limits.

Token Buckets: Controlling Rate Over Time

A token bucket enforces sustainable request rates, not just concurrent capacity:
  • Bucket holds tokens (like drink tickets)
  • Tokens refill at steady rate (e.g., 10 tokens/second)
  • Each request "costs" tokens
  • No tokens = wait for refill, even if concurrency allows
This prevents "burst then throttle" patterns. Instead of 1000 rapid requests followed by systematic failures, the token bucket smooths traffic to match your entitlement (e.g., 600 requests/minute), absorbing short bursts while maintaining sustainable long-term rates.

Why You Need Both

For robust foundation model traffic management:
  1. Semaphores prevent local resource exhaustion (connection pools, memory, CPU)
  1. Token buckets prevent remote rate limit violations (API quotas, TPM/RPM limits)
Together, they create failure-free systems: requests may queue and experience higher latency during spikes, but never fail due to capacity or rate limit violations.

The Solution: Proactive Rate Limiting

Instead of allowing failures and retrying, shape traffic to stay within entitlement boundaries. This ensures:
  1. No quota overconsumption → No throttling by Bedrock
  1. No retries → No redundant work or cascading failures
  1. Guaranteed throughput → Requests delayed during spikes, not rejected
This trades short-term latency for long-term system stability—critical for generative AI workloads.

Token Bucket Implementation

The token bucket algorithm is ideal for foundation model traffic shaping:

Key Components

Element
Technical Meaning
Bucket Capacity (C)
Maximum burst size (tokens)
Refill Rate (R)
Steady token generation rate (e.g., 10 tokens/second)
Request Cost
Tokens consumed per request
Queue
Holds excess requests when bucket empty

How It Prevents Failures

  1. Burst Absorption: Bucket holds up to C tokens for sudden spikes
  1. Sustainable Rate: Tokens refill at steady rate R (your entitlement)
  1. No Rejections: Empty bucket queues requests instead of rejecting them

Sample Implementation

Here's a Redis-based implementation for distributed rate limiting:
Plain text
-- Refill tokens at rate R, then allow request if tokens >= required
local tokens = redis.call('INCRBY', 'bucket', -required_tokens)
if tokens < 0 then
return err("Rate limit exceeded")end


Implementation Strategy

1. Replace Retries with Proactive Limiting

Traditional Design
Foundation Model Design
Retry on failure (exponential backoff)
Never fail: Shape traffic within limits
Redrive events on retries
No redrives needed—requests delayed, not failed
Reactive backpressure
Proactive backpressure via token bucket

2. Distributed Systems Considerations

Challenge
Solution
State Synchronization
Use Redis for shared bucket state across services
Clock Drift
Use logical timestamps for token generation
Multi-Tenant Fairness
Deploy per-tenant buckets with global caps
Memory Management
Bound queue sizes to prevent resource exhaustion

Results: Why This Beats Exponential Backoff

Metric
Retry + Backoff
Token Bucket + Queue
Quota Usage
Wastes quota on retries
Efficient—no redundant requests
Peak Load Behavior
Systematic failures → cascading retries
Higher latency, no failures
Throughput
Unpredictable (drops during throttling)
Predictable: Sustains rate after burst
System Stability
Fragile; cascades under pressure
Resilient; absorbs spikes gracefully

Conclusion

Foundation model workloads require a fundamental shift from reactive retry patterns to proactive rate limiting. By combining semaphores for concurrency control with token buckets for rate limiting, you can build systems that gracefully handle traffic spikes without failures, quota waste, or cascading effects.The trade-off is clear: accept higher latency during spikes in exchange for predictable, failure-free operation. For generative AI applications where consistency matters more than peak performance, this approach ensures your system remains stable and cost-effective at scale.
In the next article we will dive deeper into the implementation details and results. Please comment and tell us about your use cases.
Any opinions in this article are those of the individual author and may not reflect the opinions of AWS.
Enjoyed reading this content? Let the author know!

Your likes, comments, shares, and saves help creators reach more builders.

Loading recommendations

Loading article