DynamoDB LimitExceededException

TL;DR — You issued too many control-plane operations at once (or hit a table/account limit). Up to 500 tables and indexes may be in CREATING/UPDATING/DELETING state across your account at a time. Serialize your table operations, wait for ACTIVE, and retry with backoff.

What it means

LimitExceededException: Too many operations for a given subscriber.

This is a control-plane error — it comes from CreateTable, UpdateTable, DeleteTable, index creation, restores, and similar calls, not from GetItem/PutItem/Query. DynamoDB is telling you you've exceeded a concurrency or account limit. It's an HTTP 400, and AWS lists it as OK to retry — the condition clears as in-flight operations finish.

Why it happens

  • Too many concurrent table/index operations — the cumulative number of tables and indexes in CREATING, DELETING, or UPDATING state cannot exceed 500 per account/Region. (Up to 500 simultaneous table operations are allowed per account — CreateTable, UpdateTable, DeleteTable, UpdateTimeToLive, RestoreTableFromBackup, RestoreTableToPointInTime — and only up to 250 concurrent requests when creating tables with secondary indexes.)
  • Bulk stack deploys — CloudFormation/CDK/Terraform creating or tearing down many tables (or many GSIs) simultaneously overruns the concurrency budget.
  • Account resource quotas — hitting the soft quota of 2,500 tables per account/Region, or the 50-simultaneous-import-jobs limit.
  • DynamoDB Streams misuse — calling GetRecords with a Limit greater than 1000, or more than 2 processes reading from the same streams shard at once.
  • Note: a second UpdateTable issued while the same table is still UPDATING surfaces as ResourceInUseException, not this error — but both mean "wait for ACTIVE first".

How to fix it

  1. Serialize control-plane operations — wait for a table (and each GSI) to become ACTIVE before issuing the next change to it. Poll DescribeTable and gate on TableStatus === 'ACTIVE'.
  2. Retry with exponential backoff — the limit is transient; a backed-off retry usually succeeds once in-flight operations drain.
  3. Throttle bulk deploys — split a large stack so you're not creating hundreds of tables/GSIs at once, or add explicit DependsOn ordering so they don't all fire together.
  4. Check your service quotas — if you're near the tables-per-account limit, request a quota increase in Service Quotas rather than retrying forever.
  5. Add GSIs one at a time — you can create or delete only one global secondary index per UpdateTable operation, so serialize index changes and wait for each backfill.

FAQ

How do I fix LimitExceededException in DynamoDB? Stop issuing control-plane operations (CreateTable/UpdateTable/DeleteTable/index changes) in parallel. Wait for each table and index to reach ACTIVE before the next change, keep the count of tables in CREATING/UPDATING/DELETING under the account cap, and retry with exponential backoff.

Is LimitExceededException a throttling error? It's a control-plane concurrency/limit error, not data-plane throttling. Data-plane throttling surfaces as ProvisionedThroughputExceededException, ThrottlingException, or RequestLimitExceeded instead.

Point DynoTable at Local

DynoTable is a data-plane client — GetItem, Query, and Scan do not consume the control-plane concurrency budget this error guards. If a deploy script hits LimitExceededException while creating tables, use DynoTable to browse tables that already reached ACTIVE and validate schema from Table settings while your IaC retries. For local stacks, run DynamoDB Local with -sharedDb and connect via a Local profile (Running DynamoDB Local) so you can inspect partial deploys without waiting for every GSI to finish in AWS. The single-table design planner helps sketch table shapes before you fire another CreateTable in a busy account.

Sources

Work with DynamoDB without the Console

A fast DynamoDB desktop client that runs the real SQL DynamoDB can’t — JOINs, GROUP BY, aggregates — with visual editing and an AI agent on your own Bedrock keys.

Free 30-day trial, no credit card — then the Free plan with no time limit.