How to Reduce DynamoDB Throttling
Published on · Updated on
Rewrote throttling diagnosis, capacity guidance, monitoring, pagination, batch handling, and retry examples using current DynamoDB behavior.
DynamoDB throttles a request when it reaches a throughput or service limit. The fix depends on which resource and limit are involved: adding table capacity will not clear a hot key, an undersized global secondary index, or a configured on-demand maximum. Start with the throttling reason and affected resource, then change the matching part of the workload or table design.
- Read the exception's
ThrottlingReasonsand resource ARN before changing capacity. - Use CloudWatch to confirm whether throttling is at the table, index, or partition-key range.
- Use bounded SDK retries for transient throttling and explicitly retry unprocessed batch items.
AWS's DynamoDB throttling guide groups the main causes into partition limits, provisioned capacity, account quotas, and configured on-demand maximums.
Common causes of DynamoDB throttling

Throttling is not a single signal that the whole table needs more capacity. It can be localized to one partition-key range or index, or arise because a table-level throughput limit has been reached.
Traffic exceeds table or index capacity
In provisioned mode, the affected table or global secondary index (GSI) may not have enough read or write capacity for sustained demand. A GSI has its own provisioned read and write capacity. A busy table can therefore throttle on an index even when the table's own capacity looks sufficient. In on-demand mode, requests can still hit account-level throughput quotas or a maximum throughput configured for the table or index.
Uneven data distribution creates a hot key range
DynamoDB distributes data according to partition keys. If a large share of requests targets one partition key value, or a narrow range of values, that portion of the table or index can throttle while overall table capacity remains available. A monotonically increasing sort key under a shared partition key can concentrate writes in that key range. By contrast, distinct timestamp values used as partition keys are hashed and do not create a hotspot by themselves; the risk depends on how traffic is distributed across those keys. A popular user, product, or tenant can also concentrate reads or writes. Adaptive capacity can help with skew, but it does not remove the per-partition limits.
Scans and broad reads consume capacity
A table scan reads items across the table and can consume substantial read capacity. A Query is usually more selective when its key condition identifies the partition key and limits the sort-key range, but repeated queries against the same partition key can still create a hot key. A filter expression is applied after items have been read, so it does not reduce the read capacity consumed. A projection expression reduces the response payload, but DynamoDB calculates read capacity from the size of the items read, not just the attributes returned.
Find the throttling reason before changing capacity
DynamoDB includes one or more throttling reasons with supported throttling exceptions. Each reason combines the resource type (Table or Index), operation (Read or Write), and limit suffix. The exception also identifies the affected table or index by ARN. Record both fields with the operation and request ID so you can distinguish, for example, a GSI write limit from a base-table write limit.
{
"ThrottlingReasons": [
{
"reason": "IndexWriteProvisionedThroughputExceeded",
"resource": "arn:aws:dynamodb:us-west-2:123456789012:table/Orders/index/ByStatus"
}
]
}
This is an illustrative exception fragment, not a complete response. AWS defines the reason and resource fields in its ThrottlingReason API reference. Match the suffix to the first diagnostic step:
KeyRangeThroughputExceeded: traffic to a partition-key range is too concentrated. Investigate the table or index key distribution.ProvisionedThroughputExceeded: the named table or index exceeded its provisioned read or write capacity.AccountLimitExceeded: an on-demand table or index reached an applicable regional account service quota. Check Service Quotas for the account and Region.MaxOnDemandThroughputExceeded: the table or index reached a maximum throughput limit configured for on-demand mode. Review that guardrail and the workload's cost bounds.
The full reason starts with the affected resource and operation, such as TableReadKeyRangeThroughputExceeded or IndexWriteProvisionedThroughputExceeded. See AWS's throttling diagnosis workflow for the complete reason list and resolution guidance.
Use CloudWatch metrics to confirm the scope

Use DynamoDB's AWS/DynamoDB CloudWatch metrics to confirm the pattern and watch whether a change helps. These metrics are aggregated over time; they complement the exception detail rather than replacing it.
ThrottledRequestsis a request-level signal for provisioned-throughput throttling. For batch operations, it increments only when all individual operations in the batch are throttled, so partial batch failures may not appear here.ReadThrottleEventsandWriteThrottleEventscount item-level events that exceed provisioned capacity. Compare them withThrottledRequeststo understand the request impact.- Reason-specific throttle metrics include
ReadKeyRangeThroughputThrottleEvents,WriteKeyRangeThroughputThrottleEvents, and the corresponding*ProvisionedThroughputThrottleEvents,*AccountLimitThrottleEvents, and*MaxOnDemandThroughputThrottleEventsmetrics. Use the metric that matches the exception reason. ConsumedReadCapacityUnits,ConsumedWriteCapacityUnits, and provisioned-capacity metrics help assess provisioned workloads. Compare matching table or index dimensions over the same period; an average can hide a short spike.
For a GSI, include both TableName and GlobalSecondaryIndexName when viewing metrics. A table-only dimension does not show the index's separate metric series. If the reason indicates a hot key, CloudWatch Contributor Insights for DynamoDB can identify frequently accessed or throttled keys in a table or index. Review its billing and the key data it exposes before enabling it. See AWS's DynamoDB metrics and dimensions for metric definitions and dimensions.
Identify a hot partition or key
DynamoDB designs each partition to support up to 3,000 read units per second and 1,000 write units per second. These are capacity units, not request counts: one read unit covers one strongly consistent read per second (or two eventually consistent reads) for an item up to 4 KB, and one write unit covers one write per second for an item up to 1 KB. Larger items consume more units. A table can therefore hit a key-range limit well before its aggregate capacity is used.
Design partition keys to spread the workload, not only to create many distinct values. A high-cardinality key helps only when active traffic is distributed among those values. Where a workload must write to one logical entity at high volume, write sharding can distribute writes among shard keys, at the cost of reading from multiple shards and merging results. Apply the same scrutiny to a GSI's partition key. AWS's partition-key design guide covers distribution and sharding tradeoffs.
Separate the data-model issue from a capacity shortage
When a request is throttled, inspect its reason and ARN first. Then compare them with CloudWatch event metrics, table and index capacity, the affected operation, and the application's request rate. A sustained rise in demand may need a capacity change; a concentrated key needs a data-distribution or traffic-shaping change. A GSI reason points to that index even when the caller wrote to the base table. Avoid treating a healthy aggregate utilization graph as proof that no partition or index is constrained.
Choose the fix that matches the limit
Fix a hot key range
Spread reads and writes across partition-key values. For time-series data, consider a composite key or bounded time buckets rather than placing every write under one timestamp prefix. For an unavoidable hot logical key, write sharding can distribute writes; design reads to fan out over the relevant shards and combine results. Rate-limit concentrated producers when the data model cannot be changed immediately. Increasing total table capacity alone does not raise the maximum throughput for one hot partition-key range.
Right-size provisioned capacity and plan for scaling delay
If the reason identifies provisioned throughput, raise the capacity of the exact table or GSI that is short, or adjust its Application Auto Scaling policy and capacity bounds. Autoscaling is reactive: DynamoDB evaluates provisioned usage in one-minute periods, and AWS documents that alarms can take a few minutes to trigger and the capacity update can take several more minutes. Keep enough baseline capacity for traffic while scaling catches up. For a predictable launch or scheduled event, consider scheduled scaling or increasing capacity ahead of time. See AWS's guide to DynamoDB Auto Scaling.
Check GSI write backpressure
Each base-table write that changes indexed data can require a write to one or more GSIs. If a GSI's provisioned write capacity is too low, the index can throttle the base-table write that triggered its update. Increase or autoscale that GSI's write capacity, reduce unnecessary index write work, or revisit the index design. Adding an index is useful when it supports a required access pattern, but it adds storage and write work and can create its own hot key range. AWS explains this behavior in its guide to global secondary indexes.
Choose and prepare on-demand throughput deliberately
On-demand mode removes the need to set provisioned read and write units, but it does not remove hot partition limits, regional service quotas, or a configured maximum throughput. DynamoDB instantly accommodates traffic up to twice a table's previous peak. A sudden rise beyond twice the previous peak within 30 minutes can throttle while capacity adjusts. For a known peak, check the table and GSI's current warm throughput and consider requesting higher warm throughput in advance; the operation can take time and proactive increases may incur charges. A warm-throughput value does not override partition, quota, or configured maximum limits. Review AWS's current guidance for on-demand scaling and warm throughput.
Reduce unnecessary or concentrated work
Prefer a key-selective Query to a full table scan when the access pattern supports it, and use a key condition to narrow the partition and sort-key range. A filter expression only removes items after they have been read. A projection expression can reduce network payload, but it does not reduce read capacity for the same items. DynamoDB returns up to 1 MB per Query; continue with the returned LastEvaluatedKey until it is empty. Pagination bounds each response, but does not by itself reduce total capacity used—pace bulk reads and writes to avoid bursts. See AWS's Query API reference.
An index can make a selective query possible, but it has its own key distribution and, for a GSI, write capacity consumption. A cache can lower repeated reads when its hit rate and freshness rules fit the application, but it does not address write throttling, index backpressure, a configured limit, or traffic concentrated on cache misses. Avoid adding an index or cache until the throttling reason and access pattern show that it addresses the actual bottleneck.
Use bounded retries and handle partial batch results
AWS SDK clients already retry many throttling and transient errors according to their retry policy. Check the policy and attempt limit for the SDK and version you use, and fit retries within the caller's deadline. Increasing the attempt count can help with short-lived throttling, but it does not add capacity; retries can extend latency and increase pressure during a sustained overload. Avoid wrapping an SDK client in a second unbounded retry loop. AWS's JavaScript SDK guide describes the client's retry configuration and error handling.
This Node.js example uses AWS SDK for JavaScript v3. It assumes the package is installed, AWS credentials and a Region are configured, and the table and key exist. maxAttempts includes the initial request; choose the value to fit the operation's deadline. The SDK performs its own retry handling, while the catch block records the reason and resource if retries are exhausted.
import { DynamoDBClient, GetItemCommand } from "@aws-sdk/client-dynamodb";
const client = new DynamoDBClient({ maxAttempts: 5 });
try {
await client.send(new GetItemCommand({
TableName: "Orders",
Key: { orderId: { S: "example-order" } }
}));
} catch (error) {
const reasons = error?.ThrottlingReasons ?? [];
for (const reason of reasons) {
console.error({
reason: reason.reason,
resource: reason.resource,
requestId: error.$metadata?.requestId
});
}
throw error;
}
Batch APIs can succeed while returning only some requested work as unprocessed. Retry just the entries in UnprocessedItems from BatchWriteItem or UnprocessedKeys from BatchGetItem, using exponential backoff with jitter. This example shows the write case. It assumes writes is an array of at most 25 items with distinct primary keys for the Orders table and uses the document client.
import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
import { DynamoDBDocumentClient, BatchWriteCommand } from "@aws-sdk/lib-dynamodb";
const client = DynamoDBDocumentClient.from(new DynamoDBClient({ maxAttempts: 3 }));
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
const hasUnprocessed = (items) =>
Object.values(items).some((requests) => requests.length > 0);
let pending = {
Orders: writes.map((Item) => ({ PutRequest: { Item } }))
};
let retries = 0;
const maxRetries = 8;
while (hasUnprocessed(pending)) {
const response = await client.send(
new BatchWriteCommand({ RequestItems: pending })
);
pending = response.UnprocessedItems ?? {};
if (!hasUnprocessed(pending)) break;
if (retries >= maxRetries) {
throw new Error("Batch write still has unprocessed items after retries");
}
const delayCapMs = Math.min(1000, 50 * 2 ** retries);
await sleep(Math.floor(Math.random() * delayCapMs));
retries += 1;
}
The example makes one initial call plus up to eight follow-up calls for partial results; an SDK-level exception can still fail the operation after the SDK's configured attempts. In production, record or durably queue any items that remain before failing the job. DynamoDB accepts up to 25 write operations per BatchWriteItem call, and AWS recommends exponential backoff for unprocessed items. Do not resubmit the full original batch after a partial response, because some writes may already have succeeded. See the BatchWriteItem API reference.
Prevent future throttling
After addressing the cause, compare the same exception reasons and CloudWatch metrics before and after the change. Confirm that the affected table or index now meets the application's latency and completion goals under representative traffic.
Review capacity and access patterns
Track throttling alongside consumed and provisioned capacity, and review spikes against deployments, scheduled jobs, and traffic changes. Keep table and GSI metrics separate. For brief spikes, DynamoDB's burst-capacity guide explains what unused provisioned throughput can and cannot absorb.
Set alerts that lead to an action
Alarm on throttling that affects a service objective, or on a sustained condition that gives an operator time to act. Choose a threshold and evaluation window from the workload's tolerance and metric cadence; there is no universal utilization percentage that guarantees protection from throttling. See the site's guide to CloudWatch alarm thresholds and conditions for choosing useful alarm behavior.
Test expected traffic changes
Exercise known peak patterns in a representative environment, including the busiest partition keys and index write paths. For a planned on-demand traffic increase, check warm throughput and configured maximums ahead of the event. Monitor the actual exception reasons, throttling events, latency, and batch leftovers during the test.
Summary
To reduce DynamoDB throttling, diagnose the reason and resource ARN first. A hot partition needs a better distribution or controlled traffic; provisioned throughput throttling needs more capacity on the named table or index; on-demand quota and configured maximum errors need their respective limit reviewed. Account for GSI write backpressure, use SDK retries within a request deadline, and retry only unprocessed batch entries. Verify the fix with the same reason-specific CloudWatch metrics and workload pattern that exposed the problem.