DynamoDB Hot Partition Throttling: Find It and Fix It

Logeshwaran.C
—

A DynamoDB "hot partition" throttles requests because every partition key in the table is capped at 3,000 read capacity units and 1,000 write capacity units per second—no matter how much total throughput you've provisioned or how generous your on-demand ceiling is. That means a table happily sitting at 2% of its overall capacity can still throw ProvisionedThroughputExceededException or a ThrottlingException all day long, for one reason: too many requests are landing on the same partition key value.

The counterintuitive part is the one line almost nobody explains clearly: DynamoDB does not throttle based on how much capacity your table has left. It throttles based on how much capacity one partition has left. A table can be practically empty, capacity-wise, and still choke because 40% of your traffic is aimed at one customer ID, one status flag, or one "hot" item.

⚡ Quick Answer

• Wait and check → DynamoDB often self-heals a hot partition automatically within minutes — see split-for-heat before you touch anything

• Confirm it's a hot partition → Check ReadKeyRangeThroughputThrottleEvents / WriteKeyRangeThroughputThrottleEvents in CloudWatch

• Find the culprit key → Turn on CloudWatch Contributor Insights for DynamoDB in Throttled keys mode

Raising provisioned capacity or switching to on-demand almost never fixes this — the per-partition cap follows you either way. See how to confirm it and the fix order below.

What's actually happening when "one key" throttles a whole table

Jake runs a small mobile phone shop, and about a year ago he let his nephew build him a simple loyalty app on top of DynamoDB — customers scan a QR code at checkout, the app writes a point transaction, and a dashboard shows lifetime points. It worked fine for months. Then Jake ran a weekend flash sale and pushed the QR code out on a WhatsApp broadcast to his 4,000-customer list, all pointing at one "STORE-COIMBATORE-01" record that tracked the running total. Within twenty minutes, writes started failing. The table's provisioned write capacity was barely half used. Nothing in the AWS bill suggested a capacity problem. And yet every third scan at the register was throwing an error, and Jake was manually re-entering points by hand while a line formed.

That's a hot partition, and the reason it's confusing is that most people learn DynamoDB capacity as a table-level number — "I provisioned 2,000 write capacity units, so I have 2,000 WCU to spend." That's true in aggregate, but DynamoDB doesn't spend it that way. Behind the scenes, DynamoDB splits every table into physical partitions and divides your table's total throughput across those partitions. DynamoDB enforces specific throughput limits at the partition level for both the table and any GSI, and when concentrated traffic exceeds those limits, that partition throttles while other partitions may remain completely underutilized. It does not matter if the other 39 partitions in your table are idle. That one partition hit its wall, and every request mapped to it gets rejected until traffic backs off.

🙋‍♂️ Jake's Reality Check

"Wait — so I paid for capacity I wasn't even using, and it still throttled me? That feels like a scam."

It isn't, but it is genuinely counterintuitive. DynamoDB's whole pitch is "provision throughput at the table level and forget partitions exist." That promise holds as long as your traffic is spread across enough distinct key values. The moment one key value becomes a magnet — a single store ID, a single popular product, a single "status: pending" flag — the table-level number stops being the thing that limits you. The partition-level number takes over, and it's a fixed ceiling per partition, independently for reads and writes, full stop.

Jake's mistake wasn't the app, and it wasn't under-provisioning. It was the primary key design: one partition key value ("STORE-COIMBATORE-01") receiving effectively all the write traffic for that event. DynamoDB had no way to spread that load, because a partition key value always lives on exactly one physical partition at a time. This is by design, and it's the trade-off DynamoDB makes for the speed it gives you on single-item lookups.

📚 READ THESE FIRST

Five short reads that make everything below click into place:

⚡ Two minutes each. Come back here when they are done.

The four reasons DynamoDB throttles you — and why only one of them is "hot partition"

Not every throttled request is a hot partition problem, and treating every ThrottlingException the same way wastes time. DynamoDB's own throttling guide breaks it down into four primary reasons it may throttle requests in provisioned and on-demand mode, and the fix for each one is completely different.

Throttling reason What's actually happening CloudWatch metric to check
Key range throughput exceeded (hot partition) Traffic concentrated on one or a few partition keys blows past the fixed per-partition cap, regardless of your table's overall capacity. ReadKeyRangeThroughputThrottleEvents / WriteKeyRangeThroughputThrottleEvents
Provisioned throughput exceeded Your total consumption on a provisioned-mode table or GSI genuinely exceeds the RCU/WCU you configured. ReadProvisionedThroughputThrottleEvents / WriteProvisionedThroughputThrottleEvents
Table-level or account-level quota exceeded On-demand tables have a default per-table quota of 40,000 read and 40,000 write request units (adjustable); no account-level throughput quota applies to on-demand tables. Provisioned tables share a default per-account quota of 80,000 RCU and 80,000 WCU per Region. ReadAccountLimitThrottleEvents / WriteAccountLimitThrottleEvents
On-demand maximum throughput exceeded You (deliberately, for cost control) capped an on-demand table's maximum RRU/WRU, and traffic hit that ceiling. ReadMaxOnDemandThroughputThrottleEvents / WriteMaxOnDemandThroughputThrottleEvents

This matters because DynamoDB actually publishes 16 distinct throttling reasons across these four main categories, and the general-purpose ThrottledRequests and ReadThrottleEvents / WriteThrottleEvents metrics lump all of them together, tracking when any read or write request exceeds provisioned capacity for any reason. If you only watch the top-level throttle count, you can spend a week raising provisioned capacity (fixing reason #2) while reason #1 — the one Jake actually had — sits completely untouched, because a hot partition throttles you well before the table as a whole is out of room.

Where to see the exact reason DynamoDB gave you

When a request is throttled, the SDK exception carries more detail than just "throttled." For detailed information about why the request was throttled and the ARN of the impacted resource, the ThrottlingReason field in the returned exception names which of the 16 reasons fired, and against which table or index ARN — for a hot partition specifically, you'll see a KeyRangeThroughputExceeded reason type, narrowed further into TableReadKeyRangeThroughputExceeded, TableWriteKeyRangeThroughputExceeded, or their GSI equivalents. That one field is the fastest way to stop guessing.

Before you touch anything: DynamoDB might already be fixing it

Here's the step most write-ups skip entirely, and it can save you an afternoon: DynamoDB often adapts to hot partitions through its automatic split-for-heat mechanism. If throttling events stop after a short period on their own, your table has likely already adapted by splitting the hot partition — when a partition splits, each new partition handles a smaller section of the keyspace, which helps distribute the load more evenly, and in many cases no further action is needed because DynamoDB has automatically resolved the issue.

This is separate from adaptive capacity, though the two work together. Adaptive capacity rebalances existing partitions in near real time; split-for-heat is the deeper mechanism that physically divides an overloaded partition into smaller ones over a somewhat longer window. Amazon's own warm throughput guidance points at the same behavior from another angle: over time, if your actual throughput consistently approaches the warm throughput levels, DynamoDB may split busy partitions based on observed usage patterns. If you can pre-warm capacity ahead of an expected spike — a scheduled sale, a marketing push, a known batch job — using warm throughput or raising provisioned capacity in advance gives DynamoDB more room to do this splitting before your traffic actually arrives, instead of catching up after the throttling has already started.

⚠️ Don't mistake this for a fix you can rely on

Split-for-heat is genuinely automatic, but it isn't instant, and it doesn't help at all if the traffic is a short, sharp spike that's over before the split happens — Jake's twenty-minute flash sale was exactly that shape. If throttling is still happening minutes after it started, or it's a recurring pattern (every Monday, every payday), don't wait for it to self-heal a second time. Move to diagnosis and a deliberate fix.

How to confirm you actually have a hot partition (not just undersized capacity)

Before you touch a single line of application code, get the diagnosis right. Two different-looking problems — "I need more capacity" and "I need better key distribution" — produce the same symptom (throttled requests) but need opposite fixes.

  1. Open CloudWatch and look at ReadKeyRangeThroughputThrottleEvents and WriteKeyRangeThroughputThrottleEvents for the table (and separately for any GSI), alongside ConsumedReadCapacityUnits/ConsumedWriteCapacityUnits to see overall usage patterns. If key-range events are non-zero while overall consumption is well under your ceiling, you're looking at a hot partition, not a capacity shortfall.
  2. Cross-check ReadProvisionedThroughputThrottleEvents / WriteProvisionedThroughputThrottleEvents. If these are the ones climbing and your consumption graph is pinned at the ceiling, that's genuine undersized capacity — raising it (or moving to on-demand) will actually help.
  3. Enable CloudWatch Contributor Insights for DynamoDB on the table (and the specific GSI, if that's where the throttling ARN points), keeping it in Throttled keys mode for continuous real-time alerts, since this targeted monitoring is a cost-effective way to maintain visibility into throttling issues on an ongoing basis.
  4. Identify which keys are causing the hot partition, and, if you've temporarily switched to Accessed and throttled keys mode for a deeper look, analyze the access pattern over time to see whether the hot keys are consistent or only appear during specific periods.
  5. Watch for two distinct shapes in the results: a concentrated hot key, where the same partition key keeps appearing at the top of the throttled list, versus rolling hot partitions, where different keys become hot over time because writes are moving through the keyspace in order — sequential timestamps or scan-based operations are the classic cause, and identification here is genuinely trickier because no single key stays at the top for long.

🕐 What changed: Contributor Insights got a cheaper mode

  • Before: Contributor Insights reported every data-plane operation, both accessed and throttled keys, which meant it emitted an event for every successful request too — useful, but it billed you for monitoring traffic that was never a problem.
  • Now: DynamoDB supports emitting Contributor Insights events for throttled keys only, so you can monitor throttled keys without collecting data for every accessed key, cutting monitoring cost for tables that are healthy most of the time.
  • What that means for you: leave Throttled keys mode running on every production table as a standing tripwire, and switch to Accessed and throttled keys mode only while you're actively investigating a specific incident, or trying to distinguish a concentrated hot key from a rolling one.

Turning Contributor Insights on from the CLI

If you'd rather script this than click through the console, the AWS CLI does the same job. To enable Throttled keys mode on a table:

  1. Run aws dynamodb update-contributor-insights --table-name YourTable --contributor-insights-action=ENABLE --contributor-insights-mode=THROTTLED_KEYS against the table you suspect is affected.
  2. Check the rollout with aws dynamodb describe-contributor-insights --table-name YourTable. During the switch the status shows ENABLING; once it flips to ENABLED, data starts flowing.
  3. To see everything you currently have turned on across your account, run aws dynamodb list-contributor-insights, which lists every table and index with Contributor Insights enabled, and in which mode.

Each index is scoped independently, too. If the ARN in your ThrottlingReason field points at a GSI rather than the base table, enable it there specifically with the --index-name flag — a base table and its GSIs each have their own partition structure, so the "hot" key on one is often invisible if you only watch the other.

🙋‍♂️ Jake's Reality Check — the rolling version

A different problem showed up during Coimbatore's monsoon season, when Jake's repair-ticket table (partition key: 2026-09-DD, one row per day) started throttling on and off, never on the same date twice. "This one's weirder," Jake said. "It's not always the same key that breaks — it's whatever today's date is."

Ethan: "That's not a concentrated hot key, that's a rolling one. You're writing every ticket for the day into one date-keyed row, so whichever date is 'today' is always the hottest partition in the table, every single day, by definition. Contributor Insights won't show you one villain sitting at the top — it'll show a new one every 24 hours. The fix isn't finding the bad key. The key itself is the design flaw."

The fix order: from "check this first" to "redesign the table"

Once Contributor Insights has named the offending key (or confirmed it's rolling), work down this list. Cheapest and least disruptive first; schema redesign last, because it's the one that touches the most code.

1. If it's a read hot spot, try eventually consistent reads first

This is the cheapest lever in the whole list, and it's easy to miss because it doesn't feel like a "fix." Strongly consistent reads cost double what eventually consistent reads cost in RCU. Switching from strongly consistent to eventually consistent reads consumes half the RCUs and can immediately double your effective read capacity on that partition — no schema change, no application redesign, just a flag on the read call. It only works for read throttling, and only where your application can tolerate reading data that might be a moment behind the latest write, but for a lot of read-hot dashboards and product pages, that trade-off is free money.

2. Let adaptive capacity do its job — but understand its limits

DynamoDB doesn't just shrug at a hot partition. Adaptive capacity is enabled automatically for every table at no additional cost, and it works by increasing throughput capacity for the partitions receiving more traffic. For moderate imbalance, this alone resolves a lot of throttling without you doing anything, and it works hand-in-hand with the split-for-heat mechanism described above.

⚠️ What adaptive capacity can't do

It rebalances traffic across partitions — it does not lift the fixed per-partition ceiling of 3,000 RCU / 1,000 WCU. If a single partition key value alone drives more traffic than that (Jake's flash sale did), adaptive capacity has nothing left to redistribute. One key can only ever live on one partition at a time.

3. Randomize the partition key with write sharding

This is the standard fix when one key value is genuinely, structurally hot — a single "leaderboard" row, a single popular product, a single day's date. One way to distribute writes across a partition key space is to expand the space by adding a random number to the end of the partition key values, then randomizing the writes across the larger space. So instead of every write landing on STORE-COIMBATORE-01, it lands on STORE-COIMBATORE-01.1 through STORE-COIMBATORE-01.20, spread across up to 20 physical partitions.

The trade-off is on the read side. To read all the items for a given shard group, you'd have to query the items for every suffix and then merge the results in your application — you traded a write-side hot spot for a read-side fan-out. For Jake's "running store total," that means the loyalty dashboard now issues 20 small queries and sums them, instead of one query against a single hot key. That's a fair trade for a checkout counter that can't afford throttled writes.

🙋‍♂️ Jake's Reality Check

"So now I've got twenty rows instead of one. Doesn't that make everything more complicated for basically no reason?"

Ethan: "It's complicated for the write path's benefit, not for its own sake. You had one register queue with one till — that's your old key. Sharding is putting three tills at the counter during the sale and reconciling the cash drawers at closing. Nobody wants three cash drawers on a normal Tuesday. You want them for the one hour a week you actually need the throughput."

4. Use a calculated suffix instead of a random one, if you need to read individual items

Random sharding is great for write throughput but bad for point lookups, because you don't know which shard an item landed on. A randomizing strategy greatly improves write throughput, but it's difficult to read a specific item because you don't know which suffix was used at write time; a calculated suffix strategy uses a number you derive from something you're already querying on — for example, hashing the customer's phone number modulo 20 — so both the write and any later read can recompute the same suffix deterministically, without a scatter-gather read across every shard.

5. Redesign the partition key itself

Sharding is a patch on top of a key design. The more durable fix is choosing a partition key with naturally high cardinality in the first place, applied carefully during the initial table design phase rather than retrofitted. A partition key design that doesn't distribute I/O requests effectively is what creates hot partitions in the first place, and AWS's own comparison of common key choices ranks a user ID (where the application has many users) as good uniformity, while a status code with only a few possible values, or an item creation date rounded to a day, rates as bad. If your hot key is a status flag or a date bucket — like Jake's monsoon-season ticket table — the long-term fix isn't sharding that value, it's combining it with something high-cardinality, like "ACTIVE#customer123" instead of just "ACTIVE", or a ticket ID as the sort key under a store ID partition key instead of a date as the partition key.

⚠️ This one is expensive — go in with eyes open

Partition key redesign is a fundamental change to your data model. It requires migrating all existing data, which can be resource-intensive for large tables; every piece of application code that reads or writes the table has to be updated to the new key structure; and moving to the new design often means downtime or a complex dual-write period during the transition. It's the most comprehensive fix, but it's also the one to schedule deliberately, not the one to reach for at 11 p.m. during an active incident.

✅ Why this is the one to actually aim for

Sharding fixes the symptom on an existing table without a migration. Redesigning the key fixes the cause. If you're still early enough in a project that a schema change is cheap, spend the effort designing the key correctly the first time — it's the difference between one clean table and a permanent patchwork of suffix logic sprinkled through your codebase.

What happens to BatchWriteItem and transactions when a partition is hot

Single-item throttling is straightforward: your call fails, the SDK retries with exponential backoff, and eventually either succeeds or gives up. Batch and transactional writes behave differently, and it's worth knowing the difference before you're staring at a batch operation that "half-worked."

When individual items within a BatchWriteItem request are throttled, DynamoDB does not propagate the throttling error back to your application code as a failure. Instead, it returns information about the unprocessed items in the response, and your application is responsible for retrying just those specific items. If Jake's dashboard were writing loyalty points in a batch and one item in that batch happened to hit a hot key, the rest of the batch would succeed and only that item would come back as unprocessed — miss that detail, and you'll quietly drop writes instead of seeing a clean error.

Transactions are the opposite of forgiving: for TransactWriteItems, the entire operation fails with a TransactionCanceledException if any single item in the transaction experiences throttling. One hot key inside a five-item transaction rolls back all five. If your table mixes a hot key with items that participate in transactions, that's a strong argument for fixing the hot key first, since the throttling blast radius there is larger than a plain write would suggest.

The trap almost nobody checks: a hot GSI, not a hot base table

Here's the case that eats the most debugging time, because it looks like it shouldn't be possible. Your base table's partition key is a customer ID — textbook high cardinality, evenly spread, no problem there. And you're still throttled.

The answer is almost always a global secondary index. GSI partitioning is based on the GSI's own partition key, which is often different from the base table's, and partition-level constraints apply independently to both the base table and each GSI — each has its own partition structure and its own throughput limits. So a table keyed evenly by customer ID can still have a GSI keyed by, say, order status, and even if base table access is perfectly distributed, updates to items with popular status values can create GSI hot partitions even when the base table access pattern appears well-distributed. A common cause is a low-cardinality attribute like a status flag with only a few possible values: if 80% of your items have status="ACTIVE", that alone creates a severe hot partition in a status-based GSI.

⚠️ The confusing part

Even though the throttling exception points at the GSI via ResourceArn, the operation actually being throttled is the write to the base table — DynamoDB propagates every base table write into every GSI synchronously as part of the same operation. So your application code, which never explicitly touches the GSI, still gets the throttling error, and the natural instinct is to go look for a hot base table key that doesn't exist.

The fix here isn't the same as the base table fix. Redesigning GSI partition keys means considering whether your GSI key design is creating artificial hot spots — status flags, date-only keys, boolean attributes — that concentrate reads or writes on a small number of partitions, then applying a composite key that combines the low-cardinality attribute with a high-cardinality one, or applying the same write-sharding pattern to the base table items that affect GSI distribution. There's a second, cheaper lever worth trying first, though: optimizing what the GSI even projects. Review your application's query patterns to determine exactly which attributes need to be available when querying the GSI, and limit projections to just those. When you update an attribute that isn't projected into a GSI, no write happens on that GSI at all, which can meaningfully reduce write throughput consumption during updates without touching the key design.

A second trap: the 10 GB item collection limit on local secondary indexes

If your table has one or more local secondary indexes, there's a related but different wall you can hit, and it's worth ruling out because the error looks similar but the fix is completely different. An item collection is the set of items sharing the same partition key value; because a local secondary index's indexed view is colocated in the same partition as the base table item, the item collection cannot be distributed across multiple partitions, so for a table with one or more LSIs, item collections cannot exceed 10 GB.

That produces ItemCollectionSizeLimitExceededException instead of a plain throttling exception, and it's a hard cap, not a throughput cap — it fires regardless of how much RCU/WCU you have. DynamoDB can return an estimate of item collection size in gigabytes with your write response, as a two-element lower- and upper-bound array, so you can track whether a partition key is approaching that limit before you hit it. If a customer ID (say) accumulates millions of small order records under one LSI-indexed table over years, this is the wall that eventually stops writes — not throughput throttling, but a flat storage ceiling per key.

The fix is almost always the same one: split that growing collection with a sort-key prefix or a time-bucketed sub-key so no single partition key's item collection can grow unbounded, or move the secondary access pattern to a GSI instead, since this 10 GB constraint does not apply to item collections in global secondary indexes.

Does switching to on-demand mode fix a hot partition?

Short answer: no, and this is the single most common wasted afternoon in DynamoDB troubleshooting. On-demand mode removes the table-level capacity planning problem, but it does not remove the per-partition cap. A table might have a warm throughput of 30,000 read units and 10,000 write units per second, but still experience throttling before hitting those values — likely due to a hot partition, because while DynamoDB can keep scaling to support virtually unlimited throughput, each individual partition remains limited to 1,000 write units and 3,000 read units per second, on-demand or provisioned alike.

There's also a second, unrelated on-demand throttling mode worth knowing so you don't confuse it with a hot partition: if you exceed double your previous traffic's peak within 30 minutes, you might experience throttling, and DynamoDB recommends spreading traffic growth over at least 30 minutes before exceeding your previous peak. That's a rate-of-growth throttle, not a key-distribution throttle — it fires even with perfectly even key distribution, and the fix there is pacing a launch, not redesigning a schema.

If your table is a global table, a hot key gets replicated everywhere

Global tables replicate table data across AWS Regions: when an application writes data to a replica in one Region, DynamoDB automatically replicates that write to every other replica in the global table. Each table partition in the source Region replicates its write operations in parallel with every other partition — which matters here because a hot key isn't just a problem on your primary Region's table. It's a problem on every replica's copy of that same partition key, since the replicated write still has to land somewhere, and it lands on the equivalent partition in each Region.

In practice this means a hot partition in a multi-Region global table can show up as throttling — or as replication lag — on Regions you never even directly wrote to. CloudWatch's ReplicationLatency metric, calculated per Region pair by comparing an item's arrival time against its original write time, is worth watching alongside the key-range throttle metrics on a global table: a hot key that's merely slow to fix on a single-Region table can show up as growing replication lag everywhere else if it isn't addressed. The remediation is identical to a single-Region hot partition — sharding or key redesign — but the payoff is larger, since fixing the base table's key design fixes the problem in every Region at once rather than one at a time.

Designing the next table so this never happens

Prevention is cheaper than any of the fixes above, and it comes down to one design habit: you should design your application for uniform activity across all partition keys in the table and its secondary indexes, and in general you'll use your provisioned throughput more efficiently as the ratio of distinct partition key values accessed increases relative to the total number of values.

A few patterns worth building in from day one, all traceable back to AWS's own documentation on the topic:

  • Prefer a partition key with naturally many distinct values — a device ID across a large fleet, a user ID across a real user base — over one with a small, fixed set of possible values like a status flag or a date bucket.
  • If you're doing a bulk data load, distribute the upload work by using the sort key to load one item from each partition key value, then another item from each partition key value, and so on, which keeps more of DynamoDB's underlying servers busy simultaneously and improves throughput instead of loading one partition key's items to completion before moving to the next.
  • Leave CloudWatch Contributor Insights running in Throttled keys mode on every production table permanently. It costs nothing when nothing is throttling and gives you the answer immediately when something does.
  • Treat every new GSI's partition key with the same scrutiny as the base table's — a low-cardinality GSI key is the single most common "invisible" hot partition, because nobody thinks to check the index separately from the table.
  • If you know a traffic spike is coming — a sale, a launch, a marketing send — pre-warm the table ahead of time rather than reacting to the first round of throttling. It gives DynamoDB's own splitting mechanisms a head start.

The hard cases: when the key genuinely has to be one value

Sometimes the business problem really is "everyone needs to read or write the same logical thing" — a global counter, a live leaderboard, a single popular product page. Sharding still applies, but there's an honest limit to be named here.

⚠️ What we cannot promise

If your access pattern truly requires a single, globally consistent value updated at very high frequency — not sharded, not eventually merged — DynamoDB's per-partition cap is a real architectural ceiling, not a tuning problem. At that point the honest options are: accept a sharded-and-merged approximation (fine for a leaderboard, not fine for a bank balance), move the hot counter to a service built for exactly that pattern, or accept eventual consistency in the read path so the write path can stay sharded. There is no setting that removes the 1,000 WCU / 3,000 RCU per-partition limit itself.

Ethan's blunt version of this, the one he gives Jake every time this comes up: "If you need one number that's always exactly right and updates a thousand times a second, DynamoDB will fight you on the write side no matter what you do. Shard it, or move that one number somewhere built for hot counters. Don't spend three weeks tuning a table that's telling you it's the wrong tool for this one job."

A note on reads: caching helps, but it isn't the fix for writes

Everything above applies equally to hot reads and hot writes, but they don't take the same countermeasures. A hot read pattern — thousands of clients reading the same popular item — can often be absorbed by caching in front of DynamoDB, since a cache hit never touches the partition at all. Eventually consistent reads, covered above, are the free first step; a caching layer is the next one if that alone isn't enough. A hot write pattern has no equivalent shortcut: every write has to land on DynamoDB eventually, so sharding (or redesigning the key) is the only real lever. If Contributor Insights shows your throttling is concentrated on ReadKeyRangeThroughputThrottleEvents specifically, check whether eventually consistent reads or a caching layer is cheaper to add than a schema change. If it's WriteKeyRangeThroughputThrottleEvents, go straight to sharding or key redesign — neither of those read-side tricks will touch it.

Do you need a third-party monitoring tool, or is native CloudWatch enough?

Once you've been burned by a hot partition once, it's tempting to reach for a paid observability platform as insurance. Worth being honest about what you're actually buying, because for the specific job of catching a hot partition, native CloudWatch plus Contributor Insights already covers the core loop: the key-range throttle metrics tell you that a partition is hot, Contributor Insights tells you which key, and the ThrottlingReason field on the exception tells you which resource. That's the whole diagnostic chain, built in, at no extra service to configure.

What a third-party dashboard genuinely adds on top isn't better hot-partition detection — it's usually one of two things: unifying DynamoDB alongside every other AWS service you run so on-call engineers have one dashboard instead of switching consoles, or longer metric retention and more flexible alerting rules than the CloudWatch console gives you out of the box. If your team already lives in a third-party observability platform for everything else, point it at the DynamoDB CloudWatch namespace and set an alert on the key-range throttle metrics — that's a genuinely good use of it. If DynamoDB is the only service you're worried about, standing up a new tool purely to watch two CloudWatch metrics that are already free to view is solving a problem you don't have yet.

Every DynamoDB throughput ceiling, at a glance

Hot partitions get confused with every other kind of DynamoDB throttling, so here are all the ceilings in one place, with the defaults from AWS's quotas page. Only the first row is the one this post is about, and it is the only one you cannot raise.

CeilingDefaultApplies toCan you raise it?
Per partition (the hot-partition limit)3,000 RCU and 1,000 WCU per secondEvery partition, on-demand and provisioned, base table and each GSINo: spread the key instead
Per table, on-demand40,000 read and 40,000 write request unitsEach on-demand table or GSIYes, Service Quotas
Per table, provisioned40,000 RCU and 40,000 WCUEach provisioned table or GSIYes, Service Quotas
Per account, provisioned80,000 RCU and 80,000 WCU per RegionSum of all provisioned tables and GSIsYes, Service Quotas
Per account, on-demandNoneNot applied to on-demand tablesNot applicable
Your own on-demand maximumWhatever you setA table where you capped max read/write unitsYes, it is your setting

If the throttling you are seeing is table-level under-provisioning rather than one key, our guide to ProvisionedThroughputExceededException walks through raising capacity, auto scaling and switching to on-demand.

Frequently asked questions

What's the actual difference between a hot partition and "normal" throttling?

Normal (provisioned) throttling means your total consumption across the whole table exceeded the capacity you configured — the CloudWatch consumption graph is genuinely pinned near your provisioned ceiling. A hot partition means one key value's traffic exceeded the fixed 3,000 RCU / 1,000 WCU per-partition cap while the table overall still has plenty of headroom left. Check the key-range throttle metrics against overall consumption to tell which one you have.

How do I know if my throttling is a hot partition and not undersized capacity, without waiting for the next incident?

Turn on CloudWatch Contributor Insights for DynamoDB in Throttled keys mode before the next incident, not during it. It costs nothing while your table is healthy and gives you a ranked list of throttled keys the moment throttling starts, instead of you reconstructing it after the fact from application logs.

Can a single item really throttle an entire table?

Yes, and that's the counterintuitive core of the whole problem. DynamoDB doesn't throttle based on the table's spare capacity; it throttles based on the specific partition a key lives on. One overloaded partition key can throttle requests to that key while every other key in the table continues working normally — which is exactly why the symptom often looks like "some requests fail, most don't."

Does DynamoDB ever fix a hot partition on its own?

Often, yes, for a short-lived spike. The split-for-heat mechanism can divide an overloaded partition into smaller ones so the load spreads more evenly, and if throttling events stop shortly after they start, that's frequently what happened without any manual intervention. It isn't instant, though, so a very short, sharp spike can be over before splitting kicks in, and a recurring pattern shouldn't be left to resolve itself twice.

Does switching to on-demand capacity mode fix hot partitions?

No. On-demand mode removes the need to plan table-level throughput, but the per-partition cap (1,000 WCU / 3,000 RCU) still applies to on-demand tables exactly as it does to provisioned ones. A hot partition throttles an on-demand table just as readily as a provisioned one.

What is the actual maximum throughput a single DynamoDB partition can handle?

3,000 read capacity units per second and 1,000 write capacity units per second, per partition, independently — meaning a partition can be maxed out on writes while still having read headroom, or vice versa. This cap applies regardless of capacity mode.

How does adaptive capacity help, and why didn't it save my table?

Adaptive capacity runs automatically on every table and rebalances traffic by isolating frequently accessed items onto their own partitions where possible, borrowing headroom from quieter partitions. It has no cost and needs no configuration. What it can't do is raise the hard per-partition ceiling itself — if one key value's traffic alone exceeds 1,000 WCU or 3,000 RCU, there's no partition left to rebalance onto, because that single key can only live on one partition at a time.

Does write sharding hurt my read performance?

It changes it rather than simply hurting it. A single read for one item under a random-suffix scheme becomes multiple reads (one per shard) that your application merges, which adds latency and complexity to that read path. A calculated-suffix scheme avoids the fan-out for point lookups, at the cost of needing consistent suffix logic everywhere the key is written or read. Weigh this against the alternative: an unsharded key that throttles writes outright.

Can a global secondary index have its own hot partition even when the base table is fine?

Yes, and this is one of the most missed cases. A GSI has its own partition key and its own partition structure, entirely independent of the base table's. A base table keyed evenly by customer ID can still have a GSI keyed by a low-cardinality attribute like order status, and that GSI can throttle even while the base table's own key distribution is perfect — while the exception reported points at the GSI, the operation actually throttled is the base table write that feeds it.

What is ItemCollectionSizeLimitExceededException, and is it related to hot partitions?

It's a related-but-different limit. It applies only to tables with a local secondary index and fires when a single partition key's item collection (base table items plus everything projected into the LSI) hits 10 GB. It's a storage cap, not a throughput cap, so it can happen even on a key that's never been throttled for traffic reasons — it just means that particular key has accumulated too much data over time.

Will increasing my table's provisioned capacity fix a hot partition?

No, if the diagnosis is genuinely a hot partition. Raising the table-level RCU/WCU raises the table's total ceiling, but a single overloaded partition key is still capped at 1,000 WCU / 3,000 RCU regardless of how high the table-level number goes. You'll pay more and see the same throttling on that key. Raising capacity only helps if the metrics show genuine provisioned-throughput exhaustion, not key-range throttling.

What happens to a batch write or a transaction when one item inside it hits a hot key?

They behave very differently. In a BatchWriteItem call, throttled items don't fail the whole batch — DynamoDB returns them as unprocessed items for your application to retry individually, so the rest of the batch still succeeds. In a TransactWriteItems call, one throttled item cancels the entire transaction with a TransactionCanceledException, so a hot key touching even one item in a five-item transaction rolls back all five.

Does a hot partition in a global table affect Regions I never wrote to?

It can. Global tables replicate every write to every Region's replica, and each Region's copy of that partition key faces the same throughput limits independently. A hot key that's slow to fix can show up as throttling or rising replication lag in Regions you never directly wrote to, since the replicated write still has to land on the equivalent hot partition there.

How do I pick the right number of shards when write sharding a hot key?

Start from the throughput you actually need past the per-partition cap: if a key needs roughly 4,000 WCU of write throughput and each shard tops out around 1,000 WCU, you need at least 4 to 5 shards with headroom, not exactly 4. Watch the write key-range throttle metric after rolling out a given shard count; if it's still non-zero, add more shards rather than guessing at a bigger jump. There's no fixed "correct" number across every workload — it's sized to the traffic, then re-checked against the metric.

What should I do if my access pattern genuinely needs one dominant key, like a live leaderboard or a single trending item?

Be honest about what "one dominant key" actually requires. If near-real-time approximation is acceptable (a leaderboard that's a few seconds stale), shard the writes and merge on read, same as any other hot key. If the value must be exactly, immediately correct on every write at very high frequency, DynamoDB's fixed per-partition cap is a genuine architectural constraint, not a configuration knob — at that point, the honest answer is to move that specific hot counter to a service designed for that exact pattern rather than continuing to tune the DynamoDB table around it.

Is there an account-level throughput limit for DynamoDB on-demand tables?

No. AWS applies no account-level read or write throughput quota to on-demand tables. Each on-demand table or GSI has a default per-table quota of 40,000 read and 40,000 write request units, which you can raise through Service Quotas. The 80,000 RCU and WCU per-account default applies only to provisioned tables.

📖 ALSO READ

Hitting other AWS errors? These save your next 2 a.m.:

⚡ Bookmark this page. The list grows as new guides land.

Revision note. Written September 2026, covering DynamoDB's current provisioned, on-demand, adaptive capacity, split-for-heat, global tables, and Contributor Insights behavior, including the throttled-keys-only monitoring mode. This will need a revisit if AWS changes the fixed per-partition throughput limits or restructures Contributor Insights pricing. If you're staring at a throttled table right now, take a breath — this is one of the most fixable problems in DynamoDB once you know which metric to look at first.

Related