Filter concepts by levelShowing all levels.

AWS · DynamoDB

DynamoDB

The core vocabulary, single-table design, hot partitions, and transactional guarantees

  • Query (cheap) vs Scan (expensive)Scan reads everything, then filters
  • Single-table designknown access patterns → one table, prefixed keys
  • 3,000 RU / 1,000 WU per partitiona hard ceiling, independent of table capacity
  • ConditionExpression > full transactioncheap single-item optimistic concurrency

1.DynamoDB Core Vocabulary

A table holds items (rows); each item holds attributes (columns), schemaless beyond the primary key. A partition key alone must be unique per item; a composite key (partition + sort) lets multiple items share a partition key, sorted by sort key. A Query fetches by key efficiently; a Scan reads the whole table and is expensive at any real size. A GSI has its own partition/sort key (queryable independent of the base table's key); an LSI shares the base table's partition key with a different sort key, and must be created at table creation time.

Key features

  • Partition key alone: must be unique per item. Composite key (partition + sort): partition key can repeat, but the pair must be unique
  • Query: efficient, uses the key structure directly. Scan: reads the entire table (or index), filtering happens after the read — expensive at any real table size
  • GSI: its own partition/sort key, queryable independently — can be added after table creation, up to 20 per table by default
  • LSI: shares the base table's partition key with a different sort key — must be created at table creation time, up to 5 per table
  • Every partition delivers up to 3,000 read units and 1,000 write units per second — a single item's size determines exactly how many units each operation consumes
  • DynamoDB Streams captures item-level change events (before/after images), retained for 24 hours — often consumed via a Lambda trigger
Query vs Scan

Query

  • Uses the key structure directly
  • Reads only the matching partition (+ sort range)
  • Cheap and fast at any table size

Scan

  • Reads the entire table or index
  • Filters happen after the read, not before
  • Cost grows with table size, regardless of result size
  • Query
    • Uses the key structure directly
    • Reads only the matching partition (+ sort range)
    • Cheap and fast at any table size
  • Scan
    • Reads the entire table or index
    • Filters happen after the read, not before
    • Cost grows with table size, regardless of result size

Signature

Query (key-based, cheap) vs Scan (full read, expensive) · GSI (own key, anytime) vs LSI (shared key, at creation)

Partition key alone must be unique; composite key lets the partition repeat, pair must be unique. Query uses the key structure (cheap); Scan reads everything then filters (expensive at scale). GSI: own key, addable anytime. LSI: shares the base partition key, must be defined at table creation.

2.Single-Table Design vs Relational Modeling

Single-table design stores multiple different entity types in one DynamoDB table, using generic key names (PK/SK) and prefixed values (USER#123, ORDER#456) so one table can serve many access patterns via a small set of GSIs, instead of one table per entity type. It fits well when access patterns are known and stable upfront; a relational database fits better when queries are ad hoc, evolving, or need real joins/transactions across many entity types.

Key features

  • Single-table design uses generic attribute names (PK, SK) with prefixed values (USER#, ORDER#) to store multiple entity types in one table
  • It works by pre-computing every known access pattern into the key structure and a small number of GSIs, fetched with one Query instead of multiple round trips
  • It requires access patterns to be known upfront — DynamoDB has no ad hoc joins, so an unanticipated query pattern often means a costly Scan or a redesign
  • A relational database fits better when query patterns are genuinely ad hoc/evolving, or when multi-entity ACID transactions and complex joins are core requirements
Single-table design vs a relational database

Single-table design

  • Access patterns pre-baked into PK/SK + a few GSIs
  • One Query resolves a known, related fetch
  • Requires access patterns known upfront

Relational database

  • Real joins, ad hoc queries
  • Multi-entity ACID transactions
  • Fits evolving, not-yet-known access patterns
  • Single-table design
    • Access patterns pre-baked into PK/SK + a few GSIs
    • One Query resolves a known, related fetch
    • Requires access patterns known upfront
  • Relational database
    • Real joins, ad hoc queries
    • Multi-entity ACID transactions
    • Fits evolving, not-yet-known access patterns

Command

text
PK: USER#123      SK: PROFILE       → user profile item
PK: USER#123      SK: ORDER#456     → one of that user's orders, same partition

Single-table design pre-bakes known access patterns into generic PK/SK key structures and a few GSIs, resolving multi-entity fetches in one Query — it requires access patterns to be known upfront. Prefer a relational database when patterns are ad hoc/evolving or real cross-entity transactions/joins are core requirements.

3.Hot Partitions and Adaptive Capacity

Every partition caps out at 3,000 read units and 1,000 write units per second — a poorly-chosen partition key (e.g. one popular value getting most of the traffic) creates a "hot partition" that throttles well before the table's overall provisioned/on-demand capacity is exhausted. Adaptive capacity automatically shifts throughput toward hot partitions, but designing for uniform key distribution up front is what avoids depending on it.

Key features

  • Every partition is capped at 3,000 read units and 1,000 write units per second, regardless of the table's overall provisioned or on-demand capacity
  • A hot partition occurs when a disproportionate share of traffic concentrates on one partition key value
  • Adaptive capacity automatically and transparently shifts throughput toward frequently-accessed partitions to absorb moderate imbalance
  • Larger items consume more units per operation — a 20 KB item consumes 5x the read units of a 4 KB item for the same read type
  • Access-pattern-first design (choosing a partition key that spreads load, before choosing anything else) is the primary defense — adaptive capacity is a mitigation, not a substitute for it

Per-partition throughput limits

Per-partition throughput limits
ResourceLimit per partition per second
Read units3,000 (1 strongly consistent or 2 eventually consistent reads of a 4 KB item)
Write units1,000 (writes of a 1 KB item)
A low-cardinality key concentrates traffic onto one partition

"status" key

only 2 distinct values

90% traffic → ACTIVE

one partition absorbs almost everything

Throttles at 3,000 RU/1,000 WU

far below the table's overall capacity

  • "status" key — only 2 distinct values
  • 90% traffic → ACTIVE — one partition absorbs almost everything
  • Throttles at 3,000 RU/1,000 WU — far below the table's overall capacity

Command

text
Partition key with even value distribution → load spreads across many partitions
Partition key with a dominant/popular value → hot partition, throttling below table capacity

Every partition caps out at 3,000 RU/1,000 WU per second regardless of overall table capacity — a low-cardinality or skewed partition key creates a hot partition that throttles well below the table's budget. Adaptive capacity mitigates moderate imbalance; it does not replace access-pattern-first key design.

4.Transactional APIs and Optimistic Concurrency

TransactWriteItems/TransactGetItems group up to 100 actions across tables into one all-or-nothing, serializable operation — but each item costs double the capacity units (one to prepare, one to commit), even on a canceled transaction. ConditionExpression on an ordinary PutItem/UpdateItem gives cheap optimistic concurrency (write only if a version/value still matches) without needing a full transaction.

Key features

  • TransactWriteItems: up to 100 actions, up to 4 MB aggregate, all-or-nothing, serializable isolation
  • Every item in a transaction consumes capacity twice — once to prepare, once to commit — even if the transaction is ultimately canceled
  • ConditionExpression on a plain PutItem/UpdateItem enables optimistic concurrency (e.g. "only update if version = 5") without transaction overhead
  • Transactions provide ACID guarantees only within a single Region — not supported across Regions in global tables
  • AWS's own best practice: avoid grouping operations into a transaction unless correctness genuinely requires it — simpler transactions have higher throughput and success rates

Command

text
ConditionExpression "version = :expected"   → cheap optimistic concurrency, single item
TransactWriteItems [{Put...}, {Update...}]  → all-or-nothing across multiple items, 2x capacity cost

TransactWriteItems/TransactGetItems give all-or-nothing, serializable multi-item operations at 2x capacity cost per item (prepare + commit), even on cancellation. A ConditionExpression on a plain write gives cheap single-item optimistic concurrency without transaction overhead — prefer it when a full transaction isn't genuinely needed.

Remember

  • A Scan with a filter still reads (and pays for) the entire table before discarding non-matches.
  • An LSI must be defined at table creation; a GSI can be added anytime — plan sort-key access patterns up front.
  • A low-cardinality or skewed partition key creates a hot partition that throttles below the table's overall capacity — adaptive capacity mitigates, it does not replace good key design.
  • TransactWriteItems costs double capacity per item (prepare + commit), even on cancellation — use a ConditionExpression instead for single-item optimistic concurrency.

Pro tip

  • Single-table design pays off once access patterns are known and stable — apply it too early and every new feature forces a key-structure migration.
  • DynamoDB Streams records are retained only 24 hours — a Lambda trigger is the common way to consume them before they expire.

Next up

  • ElastiCache / Managed Caching
  • Messaging — SQS
  • SNS and Event Fan-Out

Sources

  • Core components of Amazon DynamoDB — docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.CoreComponents.html
  • Best practices for designing partition keys — docs.aws.amazon.com/amazondynamodb/latest/developerguide/bp-partition-key-design.html
  • DynamoDB Transactions: How it works — docs.aws.amazon.com/amazondynamodb/latest/developerguide/transaction-apis.html
  • Checked against official AWS documentation 2026-08-22

Spotted a mistake on this page? Tell us.