Ch. 15 · AWS

AWS DynamoDB Query vs Scan

Read by key with Query, avoid full-table Scans, and add indexes to serve the access patterns you actually have.

~2 min readadvancedupdated Oct 5, 2026

DynamoDB reads either a specific set of items with Query or the whole table with Scan. A Query uses the primary key or an index and reads only matching items; a Scan reads everything and filters afterward, so its cost grows with table size.

Before you start

You should understand partition and sort keys. This article covers Query, Scan and indexes.

Step-by-step walkthrough

Step 1: Query by key, not by filter

A Query requires an equality condition on the partition key, with optional conditions on the sort key, so it reads a bounded set. Design the key so the common access pattern is a query, such as PK = user#42, SK begins_with order#. The key is the query.

Step 2: Understand why Scan is expensive

A Scan reads every item and applies the filter after reading, so it consumes read capacity proportional to the table, not the result. A FilterExpression reduces what is returned but not what is read, which surprises people who expect it to reduce cost.

Step 3: Add a secondary index for other access patterns

A global secondary index projects the attributes you need and gives an alternate partition and sort key, so a second access pattern is also a query. Each access pattern should map to a key; if it does not, the model needs another index or a different key.

Worked scenario

The query reads one user’s recent orders by key.

table: PK = user#42, SK = order#2026-01-01
Query:
  KeyConditionExpression: 'PK = :pk AND begins_with(SK, :prefix)'
  ExpressionAttributeValues: { ':pk': 'user#42', ':prefix': 'order#' }
Text

Walk through the example

The partition key narrows the read to user 42, and the sort-key condition selects their orders, so only those items are read. A Scan with the same filter would read the entire table and discard most of it, costing far more. The key design makes the common access pattern cheap.

Common mistake

Running a Scan on a production table because the access pattern was not modeled, which is slow and expensive, or expecting a FilterExpression to reduce consumed capacity, which it does not.

Verify the behavior

Compare consumed read capacity for a Query and a Scan returning the same items. Confirm a Query requires the partition key. Add a GSI and confirm the new access pattern becomes a Query.

Interview exercise

Why does a FilterExpression on a Scan not reduce cost?

Answer and reasoning

Because DynamoDB reads items first and applies the filter after, so capacity is consumed for every item examined regardless of the result. The filter only reduces the data returned. To reduce cost you must read fewer items, which means a key-based Query or an index.

Continue learning

Compare access patterns in DynamoDB access patterns and conditions in DynamoDB conditional writes. Read the AWS DynamoDB Query documentation and try the AWS interview questions.

More in AWS

read ✓AWS · mid

AWS Lambda Cold Starts and Warm Reuse

Reduce cold-start latency with smaller packages, provisioned concurrency and initialization outside the handler.

~2 min readread →
read ✓AWS · mid

AWS DynamoDB Keys and Access Patterns

AWS DynamoDB Keys and Access Patterns. Learn the reasoning, a practical example, common mistakes and an interview exercise.

~2 min readread →
esc