Rate limiting
Control how fast you read and write to DynamoDB. Rate limiting helps you stay within your provisioned capacity and avoid throttling errors.
Key features
- Fixed rate for known workloads
- Adaptive rate that adjusts based on throttling
- Metrics to track usage
Getting started
Why rate limit?
DynamoDB charges for capacity units. When you exceed your provisioned capacity, DynamoDB throttles your requests - they fail with a ProvisionedThroughputExceededException.
Rate limiting helps you:
- Stay within budget - Don't accidentally burn through capacity
- Avoid throttling - Smooth out traffic spikes
- Share fairly - Multiple processes can share capacity without fighting
Fixed rate
Use FixedRate when you know exactly how much capacity to use. The rate stays constant unless you change it.
from pydynox import DynamoDBClient
from pydynox.rate_limit import FixedRate
# Limit to 50 read capacity units per second
client = DynamoDBClient(rate_limit=FixedRate(rcu=50))
# Limit both read and write
client = DynamoDBClient(rate_limit=FixedRate(rcu=50, wcu=25))
# Allow bursts up to 200 RCU
client = DynamoDBClient(rate_limit=FixedRate(rcu=50, burst=200))
FixedRate is good for:
- Batch jobs with predictable throughput
- Background processes that shouldn't use too much capacity
- Sharing capacity between multiple workers
Adaptive rate
Use AdaptiveRate when you don't know the right rate, or when capacity varies. It automatically adjusts based on throttling feedback.
from pydynox import DynamoDBClient
from pydynox.rate_limit import AdaptiveRate
# Set max capacity, it figures out the rest
client = DynamoDBClient(rate_limit=AdaptiveRate(max_rcu=100))
# With write limit too
client = DynamoDBClient(rate_limit=AdaptiveRate(max_rcu=100, max_wcu=50))
# With custom min (won't go below this)
client = DynamoDBClient(rate_limit=AdaptiveRate(max_rcu=100, min_rcu=10))
How adaptive rate works:
- Starts at 50% of max rate
- When throttled, reduces by 20%
- When no throttle for 10 seconds, increases by 10%
- Never goes below min or above max
AdaptiveRate is good for:
- Variable workloads
- Shared tables where capacity changes
- When you're not sure what rate to use
Advanced
Checking metrics
You can see how much capacity you've used and how many times you were throttled:
from pydynox import DynamoDBClient
from pydynox.rate_limit import FixedRate
rate_limit = FixedRate(rcu=50, wcu=25)
client = DynamoDBClient(rate_limit=rate_limit)
# After some operations...
for i in range(10):
client.put_item("users", {"pk": f"USER#{i}", "name": f"User {i}"})
# Check metrics
print(f"RCU used: {rate_limit.consumed_rcu}")
print(f"WCU used: {rate_limit.consumed_wcu}")
print(f"Throttle count: {rate_limit.throttle_count}")
This is useful for:
- Monitoring your application
- Tuning your rate limits
- Debugging throttling issues
FixedRate parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
rcu |
int | None | Read capacity units per second |
wcu |
int | None | Write capacity units per second |
burst |
int | None | Burst capacity (defaults to rate value) |
About burst: DynamoDB allows short bursts above your provisioned rate. If you set burst=200 with rcu=50, you can temporarily read at 200 RCU, but you'll need to slow down afterward to stay within your average.
AdaptiveRate parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
max_rcu |
int | Required | Maximum RCU per second |
max_wcu |
int | None | Maximum WCU per second |
min_rcu |
int | 1 | Minimum RCU (won't go below this) |
min_wcu |
int | 1 | Minimum WCU (won't go below this) |
When to use each
| Scenario | Recommendation |
|---|---|
| Known, steady workload | FixedRate |
| Variable workload | AdaptiveRate |
| Batch jobs | FixedRate with high burst |
| Shared capacity | AdaptiveRate |
| Multiple workers | FixedRate, divide capacity by worker count |
Rate limiting with batch operations
Rate limiting works with batch operations too. The rate limiter tracks capacity used by each batch and waits if needed:
from pydynox import BatchWriter, DynamoDBClient
from pydynox.rate_limit import FixedRate
client = DynamoDBClient(rate_limit=FixedRate(wcu=50))
with BatchWriter(client, "users") as batch:
for i in range(1000):
batch.put({"pk": f"USER#{i}", "name": f"User {i}"})
# Rate limiter ensures we don't exceed 50 WCU
Tip
When doing bulk writes, combine rate limiting with batch operations. This gives you both efficiency (fewer API calls) and control (predictable throughput).