Skip to content

DynamoDB features and quotas

This page is the reference for the parts of DynamoDB that shape a table design: how indexes behave, what the API operations cost and limit, and the quotas that a design has to fit inside. Concepts are introduced on the DynamoDB overview.

  • Partition key (hash key) — required on every item. On a table with no sort key it must be unique.
  • Sort key (range key) — optional. With a partition key it forms a composite key, and items sharing a partition key are stored in sort key order.
  • Item size — maximum 400 KB, including attribute names and values.

Local secondary index (LSI)

  • Must be created when the table is created and cannot be added later.
  • Same partition key as the base table, different sort key.
  • Up to 5 per table.
  • Shares the table’s provisioned throughput.

Global secondary index (GSI)

  • Can be created and deleted at any time.
  • Different partition key and/or sort key from the base table.
  • Up to 20 per table by default.
  • Has its own throughput settings, independent of the table.

An index stores only the attributes you project into it. The choice is a direct trade-off between index size, write cost and how often a query has to fetch the rest of the item from the base table.

If a query needsProjectCostEffect
A few attributes, as fast as possibleJust those attributesMinimalLowest latency for non-key access
Some non-key attributes frequentlyThose attributesModerateAvoids the cost of table scans
Most non-key attributesThose attributes, or the whole itemUp to double the storage and write costMaximum query flexibility
Rarely queried, frequently writtenKeys onlyMinimalCheapest writes for non-key items

Up to 100 user-specified projected attributes may be defined across all of a table’s local and global secondary indexes combined. Projecting the same attribute name into two indexes counts twice. The quota does not apply to indexes with a projection type of KEYS_ONLY or ALL.

An index entry only exists for items that actually carry the indexed attribute. If a Status attribute is written only on open orders, an index on Status contains only open orders — a small index that answers “list the open orders” without scanning the table, and that shrinks by itself as orders close. Sparse indexes are one of the cheapest ways to serve a selective query.

Because a GSI has independent throughput, projecting the whole item into an index with the same key schema as the table gives a second, separately provisioned copy of the data. That is useful for separating classes of traffic — analytics reads off the index while writes land on the table, or high-throughput customers on the table and lower tiers on the index. The copy is eventually consistent with the table, so it is not a substitute for a strongly consistent read.

  • Scalar — number, string, binary, boolean, null.
  • Document — list, map.
  • Set — number set, string set, binary set.
  • Deletes items automatically after an expiry timestamp held in a nominated attribute.
  • The attribute must be a number holding a Unix epoch time in seconds; one TTL attribute per table.
  • Useful for session data, staging data and logs.
  • TTL deletions are free and do not consume write capacity in the Region where they occur, though replicated deletions in a global table do.
  • TTL deletions appear in DynamoDB Streams.
  • TTL is not available on global tables configured for multi-Region strong consistency.

Query requires a partition key value and optionally a sort key condition. It reads only the matching partition, can run against any LSI or GSI, can return results in ascending or descending sort key order, and pages through results with a Limit parameter.

Scan examines every item in the table, applies any filter expression after reading, and therefore consumes capacity proportional to the table rather than to the result. It supports parallel segments for throughput. Prefer a query, or an index that turns the scan into a query.

Both cap a single response at 1 MB, after which the caller must page.

OperationLimit
BatchGetItemUp to 100 items, 16 MB per request
BatchWriteItemUp to 25 put or delete requests, 16 MB per request
TransactWriteItemsUp to 100 write actions against up to 100 distinct items, 4 MB aggregate
TransactGetItemsUp to 100 get actions against up to 100 distinct items, 4 MB aggregate

Batch operations may partially succeed and return unprocessed items for the caller to retry. Transactions are all-or-nothing. Note the difference between the two 25s and 100s above: BatchWriteItem is capped at 25 requests, transactions at 100 actions.

  • ProvisionedThroughputExceededException — the request exceeded provisioned capacity.
  • ThrottlingException — too many control-plane operations.
  • ResourceNotFoundException — the table or index does not exist.
  • TransactionCanceledException — a transaction failed; the exception lists a cancellation reason per item.

Retry with exponential backoff and jitter. The AWS SDKs do this by default for throttling errors.

ConsumedReadCapacityUnits, ConsumedWriteCapacityUnits, ReadThrottleEvents, WriteThrottleEvents, ThrottledRequests, SystemErrors, and — on eventually consistent global tables — ReplicationLatency.

QuotaDefault
Item size400 KB
Items per table, table sizeNo limit
Tables per account per Region2,500 (raisable to 10,000)
Partition key length2,048 bytes
Sort key length1,024 bytes
Attribute name length64 KB
Attributes per itemNo fixed limit, subject to the 400 KB item size
Table-level throughput40,000 read units and 40,000 write units, on-demand or provisioned
Account-level provisioned throughput80,000 read and 80,000 write capacity units per Region
Per-partition throughput3,000 read units, 1,000 write units
Global secondary indexes per table20
Local secondary indexes per table5
Projected attributes across all indexes100 user-specified
Query and scan response size1 MB
Point-in-time recovery window35 days
Streams retention24 hours

Most of these are adjustable through Service Quotas; the item size, key lengths, page size and per-partition throughput are not.

  • Choose a partition key with enough distinct values to spread load evenly.
  • Model to the queries the application actually makes; DynamoDB rewards a schema designed backwards from its access patterns.
  • Use sparse indexes to keep selective queries cheap.
  • Project the minimum set of attributes an index needs.
  • Retry with exponential backoff.
  • Batch where the semantics allow it, and reserve transactions for cases that genuinely need atomicity.
  • Compress or offload large attribute values — put the blob in S3 and the pointer in the item.