How to fix ThrottlingException: Rate exceeded in DynamoDB

DynamoDBINTERMEDIATEMEDIUMUpdated Dec 22, 2025· 107 views

DynamoDB returns ThrottlingException when your request rate exceeds the allowed throughput for your table, index, or account limits. This error occurs with both provisioned and on-demand capacity modes when you send too many requests too quickly.

Quick fix

Fixes ThrottlingException: Rate exceeded

// AWS SDK v3 for JavaScript automatically handles retries
import { DynamoDBClient } from '@aws-sdk/client-dynamodb';

const client = new DynamoDBClient({
  region: 'us-east-1',
  maxAttempts: 10, // Default is 3, increase for high-throughput applications
});

// For custom retry logic:
const delay = (retryCount) => {
  const baseDelay = 50; // 50ms
  const maxDelay = 5000; // 5 seconds
  const delay = Math.min(maxDelay, baseDelay * Math.pow(2, retryCount));
  const jitter = delay * 0.1 * Math.random(); // Add 10% jitter
  return delay + jitter;
};
  1. Implement exponential backoff with jitter
  2. Review and adjust provisioned capacity
  3. Enable and configure auto-scaling
  4. Address hot partition keys
dynamodb — error
// AWS SDK v3 for JavaScript automatically handles retries
import { DynamoDBClient } from '@aws-sdk/client-dynamodb';
const client = new DynamoDBClient({
region: 'us-east-1',
maxAttempts: 10, // Default is 3, increase for high-throughput applications
});
// For custom retry logic:
const delay = (retryCount) => {
const baseDelay = 50; // 50ms
const maxDelay = 5000; // 5 seconds
const delay = Math.min(maxDelay, baseDelay * Math.pow(2, retryCount));
const jitter = delay * 0.1 * Math.random(); // Add 10% jitter
return delay + jitter;
};
ThrottlingException: Rate exceeded

What this error means

The ThrottlingException error in DynamoDB indicates that your application is sending requests at a rate that exceeds the throughput limits configured for your table, global secondary index, or your AWS account. This error can occur in several scenarios: 1. **Provisioned capacity mode**: When your request rate exceeds the read or write capacity units (RCUs/WCUs) you've provisioned for a table or index 2. **On-demand mode**: When your request rate exceeds the account-level throughput limits for on-demand tables 3. **Hot partition/keys**: When requests are concentrated on a single partition key, exceeding the partition's throughput limits 4. **Control plane operations**: When performing too many administrative operations (CreateTable, UpdateTable, etc.) in quick succession DynamoDB uses throttling to maintain performance and fairness across all customers. When throttled, requests are rejected with HTTP status code 400 and the ThrottlingException error.

Typical symptoms

  • HTTP 400 errors with "ThrottlingException: Rate exceeded" message
  • Increased latency as requests are retried with exponential backoff
  • Application performance degradation during peak traffic
  • CloudWatch metrics showing high ThrottledRequests count
  • Batch operations returning UnprocessedItems or UnprocessedKeys
  • Transaction operations failing with TransactionCanceledException and ThrottlingError cancellation reason

Common causes

  1. Insufficient provisioned capacity for current workload demands
  2. Sudden traffic spikes without proper auto-scaling configuration
  3. Hot partition keys causing uneven load distribution across partitions
  4. Aggressive retry logic creating retry storms that worsen throttling
  5. On-demand tables hitting account-level throughput limits
  6. Concurrent control plane operations exceeding the 500-operation limit
  7. Global secondary index write capacity lower than base table capacity
  8. Exceeding the 2 simultaneous readers per DynamoDB Streams shard limit

How to fix "ThrottlingException: Rate exceeded"

1Implement exponential backoff with jitter

AWS SDKs automatically implement exponential backoff for throttling errors, but you should verify your configuration:

javascript
// AWS SDK v3 for JavaScript automatically handles retries
import { DynamoDBClient } from '@aws-sdk/client-dynamodb';

const client = new DynamoDBClient({
  region: 'us-east-1',
  maxAttempts: 10, // Default is 3, increase for high-throughput applications
});

// For custom retry logic:
const delay = (retryCount) => {
  const baseDelay = 50; // 50ms
  const maxDelay = 5000; // 5 seconds
  const delay = Math.min(maxDelay, baseDelay * Math.pow(2, retryCount));
  const jitter = delay * 0.1 * Math.random(); // Add 10% jitter
  return delay + jitter;
};

Key points:
- AWS SDKs handle retries automatically for throttling errors
- Increase maxAttempts for high-throughput applications
- Add jitter to prevent synchronized retry storms across multiple clients

2Review and adjust provisioned capacity

Check your current provisioned capacity and adjust based on actual usage:

bash
# Check current provisioned capacity
aws dynamodb describe-table --table-name YourTableName

# Update provisioned capacity
aws dynamodb update-table \
  --table-name YourTableName \
  --provisioned-throughput \
    'ReadCapacityUnits=100,WriteCapacityUnits=50'

# For global secondary indexes
aws dynamodb update-table \
  --table-name YourTableName \
  --global-secondary-index-updates \
    '[{
      "Update": {
        "IndexName": "YourIndexName",
        "ProvisionedThroughput": {
          "ReadCapacityUnits": 50,
          "WriteCapacityUnits": 25
        }
      }
    }]'

Best practices:
- Monitor CloudWatch metrics: ConsumedReadCapacityUnits, ConsumedWriteCapacityUnits, ThrottledRequests
- Set GSI write capacity ≥ base table write capacity
- Use auto-scaling with target utilization around 70%

3Enable and configure auto-scaling

Configure auto-scaling to automatically adjust capacity based on demand:

bash
# Register scalable target
aws application-autoscaling register-scalable-target \
  --service-namespace dynamodb \
  --resource-id "table/YourTableName" \
  --scalable-dimension "dynamodb:table:ReadCapacityUnits" \
  --min-capacity 5 \
  --max-capacity 1000

# Create scaling policy for read capacity
aws application-autoscaling put-scaling-policy \
  --service-namespace dynamodb \
  --resource-id "table/YourTableName" \
  --scalable-dimension "dynamodb:table:ReadCapacityUnits" \
  --policy-name "ReadScalingPolicy" \
  --policy-type "TargetTrackingScaling" \
  --target-tracking-scaling-policy-configuration \
    '{
      "TargetValue": 70.0,
      "PredefinedMetricSpecification": {
        "PredefinedMetricType": "DynamoDBReadCapacityUtilization"
      },
      "ScaleOutCooldown": 60,
      "ScaleInCooldown": 300
    }'

Configuration tips:
- Set TargetValue to 70% for balanced performance and cost
- Use longer ScaleInCooldown (300 seconds) than ScaleOutCooldown (60 seconds) to prevent rapid scale-in
- Monitor scaling activities in CloudWatch

4Address hot partition keys

If requests are concentrated on specific partition keys, implement strategies to distribute load:

javascript
// Example: Add random suffix to partition key
function getPartitionKey(userId) {
  const suffix = Math.floor(Math.random() * 10); // 0-9
  return `user-${userId}-${suffix}`;
}

// Example: Use composite key with timestamp
function getTimeBasedKey(entityId) {
  const hour = new Date().getHours();
  return `${entityId}-${hour}`;
}

// Example: Use write sharding for high-velocity data
function getShardedKey(streamId) {
  const shardId = streamId % 100; // Distribute across 100 shards
  return `stream-${shardId}`;
}

Strategies:
- Add random suffixes or prefixes to partition keys
- Use composite keys with timestamps for time-series data
- Implement write sharding for high-velocity streams
- Consider using DynamoDB Accelerator (DAX) for read-heavy hot keys

5Optimize batch and transaction operations

Handle partial failures in batch operations and implement proper retry logic:

javascript
// Process BatchWriteItem with retry logic
async function batchWriteWithRetry(items, tableName) {
  let unprocessedItems = { [tableName]: items };

  while (Object.keys(unprocessedItems[tableName] || {}).length > 0) {
    const response = await dynamodb.batchWriteItem({
      RequestItems: unprocessedItems
    }).promise();

    unprocessedItems = response.UnprocessedItems || {};

    if (Object.keys(unprocessedItems).length > 0) {
      // Exponential backoff with jitter
      const delay = Math.min(5000, 50 * Math.pow(2, retryCount));
      await new Promise(resolve => setTimeout(resolve, delay));
    }
  }
}

// For transactions, use ClientRequestToken for idempotency
const transactionParams = {
  TransactItems: [
    { Put: { TableName: 'Table1', Item: item1 } },
    { Update: { TableName: 'Table2', Key: key2, UpdateExpression: 'SET #count = #count + :inc' } }
  ],
  ClientRequestToken: 'unique-transaction-id-' + Date.now()
};

Best practices:
- Always process UnprocessedItems from batch operations
- Use ClientRequestToken for transaction idempotency
- Limit batch sizes to 25 items to avoid size limits

6Consider on-demand capacity mode

For unpredictable workloads, switch to on-demand capacity mode:

bash
# Switch table to on-demand mode
aws dynamodb update-table \
  --table-name YourTableName \
  --billing-mode PAY_PER_REQUEST

# Check current billing mode
aws dynamodb describe-table --table-name YourTableName \
  --query 'Table.BillingModeSummary.BillingMode'

When to use on-demand:
- Unpredictable or spiky workloads
- New applications with unknown traffic patterns
- Development and testing environments
- Applications with low to moderate traffic

Limitations:
- Account-level throughput limits still apply
- Can be more expensive for steady, predictable workloads
- Switching back to provisioned mode requires 24-hour wait

Advanced notes

## Throttling Diagnostics and Monitoring

### CloudWatch Metrics to Monitor:
- ThrottledRequests: Count of throttled read/write requests
- ConsumedReadCapacityUnits / ConsumedWriteCapacityUnits: Actual capacity used
- ProvisionedReadCapacityUnits / ProvisionedWriteCapacityUnits: Configured capacity
- UserErrors: Client-side errors including throttling
- SystemErrors: Server-side errors

### ThrottlingReason Analysis:
DynamoDB returns detailed throttling reasons in error responses:
- TableReadProvisionedThroughputExceeded: Table read capacity exceeded
- IndexWriteProvisionedThroughputExceeded: GSI write capacity exceeded
- TableReadKeyRangeThroughputExceeded: Hot partition key read throttling
- IndexWriteMaxOnDemandThroughputExceeded: On-demand index write limit
- TableWriteAccountLimitExceeded: Account-level write limit

### Partition Throughput Limits:
Each partition in DynamoDB has limits:
- Provisioned mode: 3000 RCUs and 1000 WCUs per partition
- On-demand mode: Higher limits but still subject to partition constraints

### DynamoDB Streams Throttling:
- Maximum 2 simultaneous readers per shard
- Use Kinesis Data Streams for higher fanout needs
- Monitor ReadThrottleEvents metric

### Best Practices for High-Throughput Applications:
1. Implement circuit breakers to fail fast during sustained throttling
2. Use connection pooling to limit concurrent requests
3. Implement request queuing with backpressure signaling
4. Consider DynamoDB Accelerator (DAX) for read-heavy workloads
5. Use AWS X-Ray to trace throttling patterns in distributed systems

### When to Contact AWS Support:
- Consistently hitting account-level throughput limits
- Need quota increases for on-demand tables
- Suspected partition imbalance issues
- Production-critical applications requiring dedicated support

Frequently asked questions

What does "ThrottlingException: Rate exceeded" mean?
The ThrottlingException error in DynamoDB indicates that your application is sending requests at a rate that exceeds the throughput limits configured for your table, global secondary index, or your AWS account. This error can occur in several scenarios: 1. Provisioned capacity mode: When your request rate exceeds the read or write capacity units (RCUs/WCUs) you've provisioned for a table or index 2.
How do I fix "ThrottlingException: Rate exceeded"?
DynamoDB returns ThrottlingException when your request rate exceeds the allowed throughput for your table, index, or account limits. This error occurs with both provisioned and on-demand capacity modes when you send too many requests too quickly.
What causes "ThrottlingException: Rate exceeded"?
Insufficient provisioned capacity for current workload demands Sudden traffic spikes without proper auto-scaling configuration Hot partition keys causing uneven load distribution across partitions
Is the "ThrottlingException: Rate exceeded" error serious?
It is a medium-severity error — more of a blocker than a risk. The steps above resolve it.

Official resources & further reading