dynobase-icon
Dynobase

DynamoDB Throttling: Why It Happens and How to Fix It

Chameera Dulanga

Written by Chameera Dulanga

Last updated: October 23rd, 2026

Investigating throttling or capacity? Dynobase shows a table's CloudWatch metrics next to its data, tails DynamoDB Streams and can refresh results automatically. Metrics and streams in Dynobase

DynamoDB throttles a read or write when serving it would exceed one of four limits: the capacity you provisioned, the maximum throughput you set on an on-demand table, the per-table throughput quota, or the throughput of a single partition (3,000 read units and 1,000 write units per second). A throttled request fails with an HTTP 400 error, which the AWS SDKs retry automatically. Since August 2025 every throttled request carries a ThrottlingReasons list that names the limit and the table or index, and CloudWatch has a metric for each cause, such as WriteKeyRangeThroughputThrottleEvents for a hot partition.

The four causes of DynamoDB throttling

Limit typeWhat it meansCapacity modeExceptionCloudWatch metrics
ProvisionedThroughputExceededTraffic is above the table's or GSI's provisioned read or write capacity, and burst capacity is used upProvisionedProvisionedThroughputExceededExceptionReadProvisionedThroughputThrottleEvents, WriteProvisionedThroughputThrottleEvents
KeyRangeThroughputExceededOne partition is receiving more than 3,000 read units or 1,000 write units per secondBothProvisionedThroughputExceededException (provisioned) or ThrottlingException (on-demand)ReadKeyRangeThroughputThrottleEvents, WriteKeyRangeThroughputThrottleEvents
MaxOnDemandThroughputExceededTraffic is above the maximum throughput you configured on an on-demand table or GSIOn-demandThrottlingExceptionReadMaxOnDemandThroughputThrottleEvents, WriteMaxOnDemandThroughputThrottleEvents
AccountLimitExceededAn on-demand table or GSI is above the per-table throughput quota (40,000 read and 40,000 write request units by default)On-demandRequestLimitExceededReadAccountLimitThrottleEvents, WriteAccountLimitThrottleEvents

Each reason is built as Table or Index, then Read or Write, then the limit type, so you get values such as TableWriteKeyRangeThroughputExceeded or IndexReadProvisionedThroughputExceeded. The resource field holds the ARN of the throttled table or index. The older metrics ReadThrottleEvents, WriteThrottleEvents and ThrottledRequests still exist and count every cause together.

The legacy event metrics count items, not calls: a BatchGetItem that reads 10 items is processed as 10 read events, so ReadThrottleEvents can rise while ThrottledRequests goes up only if all 10 are throttled.

Find out which limit you hit

In your code

With retries enabled, the SDK retries eligible throttled requests with backoff before surfacing the final exception. The attempt count depends on your SDK and retry configuration. The reasons come with the exception. You need an SDK version released after August 2025 to see them, and note the field name: ThrottlingException uses throttlingReasons, while ProvisionedThroughputExceededException and RequestLimitExceeded use ThrottlingReasons.

In Python the reasons are in the parsed error response:

The adaptive retry mode adds client-side rate limiting on top of backoff, which helps a batch job slow itself down instead of hammering a throttled table. The error pages for ProvisionedThroughputExceededException and ThrottlingException cover the messages in more detail.

In CloudWatch and the console

Graph the eight per-cause metrics above for the table and for each GSI (use the TableName and GlobalSecondaryIndexName dimensions). The DynamoDB console also graphs throttle events broken down by cause. Set alarms on the KeyRange and AccountLimit metrics in particular, because neither is fixed by adding provisioned capacity.

To find the partition keys behind key-range throttling, turn on CloudWatch Contributor Insights for the table. Its THROTTLED_KEYS mode reports only throttled keys, and while nothing is being throttled it ingests no data and costs nothing, so you can leave it on. The default mode, ACCESSED_AND_THROTTLED_KEYS, also ranks the most-accessed keys.

If you work in Dynobase, its Metrics tab shows a table's capacity usage, throttling and latency from CloudWatch next to the data, for the table or a supported index.

Hot partitions: KeyRangeThroughputExceeded

Every partition of a table or GSI serves at most 3,000 read units and 1,000 write units per second, in both capacity modes. A table can have plenty of total capacity and still throttle when the traffic lands on one partition key. Item size counts: a 20 KB item costs 5 read units for each strongly consistent read, so a single hot item tops out at about 600 such reads per second. The capacity and item size calculator shows how many units an item costs.

DynamoDB adapts to many hot partitions on its own. Its split-for-heat mechanism moves a busy key range onto new partitions, and adaptive capacity can isolate a single hot item on a partition of its own, at no charge. Detecting and adapting takes several minutes, there is no notification, and splitting can't help in three cases:

  • One hot item. An item can't be split, so it is capped at 3,000 read units and 1,000 write units per second.
  • Ever-increasing sort keys under one partition key, such as timestamps written to device#42. Every write lands at the end of the key range, so splitting doesn't spread them and the key stays near 1,000 write units per second.
  • Tables with a local secondary index. Item collections can't be split across partitions, so one partition key value is always served by one partition.

What to do, roughly in the order AWS suggests:

  1. Find the key with Contributor Insights in THROTTLED_KEYS mode.
  2. Read less from it. Eventually consistent reads cost half the read units of strongly consistent ones, and a cache such as DAX absorbs repeated reads of the same items.
  3. Pre-warm before a known peak. Raising a table's or GSI's warm throughput gets the partitions ready before a launch or migration instead of during it.
  4. Spread the writes. Add a suffix to a hot partition key (customer#123#0 to customer#123#9) and read the shards back in parallel, or aggregate high-frequency updates such as counters before writing them. Choosing the partition key covers the patterns.
  5. Check your GSIs. A GSI whose key has few distinct values (status = ACTIVE) throttles on its own partitions, and a throttled GSI throttles writes to the base table, because every base-table write must also update the index. Use a higher-cardinality GSI key; since November 2025 a GSI key can combine up to four partition-key and four sort-key attributes.

Provisioned tables: ProvisionedThroughputExceeded

DynamoDB console read/write capacity settings with provisioned mode selected and auto scaling on, showing minimum capacity units, maximum capacity units and target utilization

A provisioned table throttles when consumed capacity stays above its provisioned capacity per second. Two mechanisms soften this, and both have limits:

  • Burst capacity. DynamoDB retains up to five minutes (300 seconds) of unused read and write capacity and spends it on short spikes. AWS can also use it for background maintenance without notice, so treat it as a cushion, not as capacity.
  • Auto scaling. Auto scaling raises capacity only after consumed capacity breaches the target utilization for two consecutive minutes, and spikes more than a minute apart might not trigger it. The UpdateTable call it makes then takes several minutes, and requests above the old capacity are throttled in the meantime. Scaling down happens after 15 consecutive data points below the target, and by default each table or GSI can be scaled down at most 27 times a day (4 decreases at any time plus 1 more for each hour without one).

Auto scaling therefore handles traffic that ramps over minutes, not sudden spikes. For a spike you can predict, raise the minimum capacity beforehand. For traffic you can't predict, use on-demand mode: since August 2025 you can switch a table from provisioned to on-demand up to four times in a rolling 24 hours, and back to provisioned at any time. The on-demand vs provisioned comparison covers when each mode wins.

On-demand tables: when they still throttle

DynamoDB console read/write capacity settings with on-demand mode selected

On-demand mode removes capacity planning, but not every limit:

  • Sudden growth. A new on-demand table can sustain up to 4,000 writes and 12,000 reads per second. After that, a table instantly accommodates up to double its previous peak, and throttling can occur if traffic exceeds double the previous peak within 30 minutes. Pre-warm with warm throughput before a launch, a migration or a load test.
  • The per-table quota. Each on-demand table and GSI is capped at 40,000 read request units and 40,000 write request units per second by default, which surfaces as RequestLimitExceeded. Request a higher "Table-level read throughput limit" or "Table-level write throughput limit" in the Service Quotas console; since February 2025 these throughput increases are approved automatically within minutes.
  • Your own maximum throughput. If you set a maximum read or write throughput on the table or a GSI to cap cost, requests above it get ThrottlingException. The cap is a target, not an exact ceiling, so short bursts can exceed it.
  • Hot partitions. The 3,000 and 1,000 units per second per partition apply exactly as they do in provisioned mode.

What happens to throttled requests

  • The SDK retries them. Throttling errors are retryable HTTP 400 responses, and the AWS SDKs retry them with exponential backoff before giving up. Each retry adds latency, so heavy throttling shows up as slow requests before it shows up as errors.
  • Unhandled write failures lose data. If retries run out and your code doesn't queue or retry the write, it never happens.
  • Batch calls return leftovers instead of failing. BatchWriteItem and BatchGetItem return throttled items in UnprocessedItems or UnprocessedKeys, and throw only when nothing in the batch could be processed. Retry the leftovers with backoff, or they are silently dropped.
  • They don't count against the SLA. The DynamoDB SLA counts only HTTP 500 and 503 responses as errors.

Fixes by symptom

What you seeLikely causeFix
*ProvisionedThroughputThrottleEvents during traffic spikesCapacity too low for the peakRaise auto scaling minimums ahead of known peaks, or switch to on-demand
*KeyRangeThroughputThrottleEvents while total capacity is idleHot partition key or hot itemContributor Insights, eventually consistent reads, caching, write sharding
*AccountLimitThrottleEvents on an on-demand tablePer-table quota of 40,000 units per secondRequest a table-level throughput quota increase in Service Quotas
*MaxOnDemandThroughputThrottleEventsYour configured on-demand maximumRaise or remove the maximum read or write throughput
Base-table writes throttled with an Index... reasonA GSI can't keep upGive the GSI a higher-cardinality key; in provisioned mode, give it enough write capacity
Throttling only right after launch or a migrationTable not yet scaled for the trafficPre-warm with warm throughput

Frequently Asked Questions

What causes DynamoDB throttling?

A request is throttled when it would exceed provisioned capacity, the maximum throughput configured on an on-demand table, the per-table throughput quota (40,000 read and write units per second by default), or the limit of a single partition: 3,000 read units and 1,000 write units per second. The ThrottlingReasons field on the error tells you which one.

What does WriteKeyRangeThroughputThrottleEvents mean?

It is a CloudWatch metric, added in August 2025, that counts write requests throttled because a single partition exceeded its limit of 1,000 write units per second. It points to a hot partition key, so adding table capacity won't fix it; spreading writes across more key values will. ReadKeyRangeThroughputThrottleEvents is the read equivalent, at 3,000 read units per second.

Can an on-demand DynamoDB table be throttled?

Yes. On-demand tables throttle when traffic more than doubles its previous peak within 30 minutes, when a table or GSI passes the 40,000 units per second table quota, when a partition passes 3,000 reads or 1,000 writes per second, or when traffic exceeds a maximum throughput you configured.

Does DynamoDB retry throttled requests automatically?

The AWS SDKs do. Throttling errors are retryable, so the SDK retries them with exponential backoff before returning the error to your code. Batch operations are different: throttled items come back in UnprocessedItems or UnprocessedKeys, and you have to retry those yourself.

What is the difference between ThrottlingException and ProvisionedThroughputExceededException?

ProvisionedThroughputExceededException comes from provisioned tables, either because the table or GSI ran out of provisioned capacity or because a partition hit its limit. ThrottlingException comes from on-demand tables that hit a partition limit or a configured maximum throughput, and from control plane calls made too quickly. RequestLimitExceeded means an on-demand table hit its throughput quota.

Dynobase is a Professional GUI Client for DynamoDB

Start your 7-day free trial today

Product Features

Download
/
Changelog
/
Pricing
/
Member Portal
/
Privacy
/
EULA
/
Twitter
© 2026 Dynobase