How to query DynamoDB by date range key, with no obvious hash key?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
In DynamoDB, you cannot query efficiently by sort key alone. A Query operation always needs a partition key value, because that key tells DynamoDB which partition to search. So if your access pattern is "give me items in this date range" and you have no obvious partition key, the real answer is not a special query trick. It is a data-model change, usually by introducing a secondary index or a synthetic partition key that matches the date-based read pattern.
Why the Base Table Query Does Not Work
A DynamoDB table with a composite primary key has two pieces:
- partition key
- sort key
The sort key supports range conditions such as between and begins_with, but only after you have already narrowed the search to one partition-key value. Without that first step, DynamoDB would have to inspect the whole table.
That is why this does not exist as a fast base-table query pattern:
- unknown partition key
- known date range
- efficient
Query
If you truly do not know the partition key and still need date-based access, you are describing a different access pattern that should have its own index design.
Option 1: Add a Date-Oriented GSI
A common solution is to create a Global Secondary Index whose partition key groups items by a time bucket, and whose sort key holds the timestamp.
For example:
- '
GSI1PK = DATE#2026-03' - '
GSI1SK = 2026-03-11T14:32:00Z#ORDER#1001'
That design lets you query one month bucket and then apply a between condition on the timestamp portion of the sort key.
A boto3 example looks like this:
This works because the query now has a partition key value for the index.
Option 2: Use a Synthetic Constant Partition Key Only at Small Scale
For low-volume data, some teams create an index with a constant partition key such as ALL_ORDERS and a timestamp sort key.
Example item attributes:
- '
GSI2PK = ALL_ORDERS' - '
GSI2SK = 2026-03-11T14:32:00Z#1001'
That makes the query simple, but it also concentrates all reads and writes onto one logical key. It can be acceptable for small datasets or internal tools, but it does not scale well for heavy workloads.
If you expect growth, use bucketed keys by day, month, tenant, region, or another dimension that spreads traffic.
Option 3: Scan Only as a Last Resort
You can always Scan the table and apply a filter expression on the date, but the important detail is that filtering happens after reading the data. It reduces returned items, not read cost.
This is fine for admin jobs, migrations, or tiny tables. It is not the answer for latency-sensitive production reads.
Pick a Timestamp Format That Sorts Correctly
If your sort key contains a date or timestamp, store it in a lexicographically sortable format such as ISO 8601 UTC.
Good example:
- '
2026-03-11T14:32:00Z'
Risky example:
- '
03/11/2026 2:32 PM'
With ISO 8601 strings, alphabetical order matches chronological order, which makes range queries behave correctly.
Think in Terms of Access Patterns
The mistake behind this question is usually not in the query syntax. It is in the schema design. DynamoDB modeling starts by asking what queries must be fast, then designing keys and indexes for those queries.
If date-range access is a first-class requirement, give it a first-class key structure. Do not hope the database can infer a partition strategy from the sort key alone.
Common Pitfalls
The biggest mistake is trying to force a relational mindset onto DynamoDB and expecting the database to search efficiently by any indexed-looking field. DynamoDB performance depends on key design, not on ad hoc predicates.
Another mistake is using a scan with a filter and calling it a query. Operationally, those are very different. A scan reads broadly; a query targets a key.
Teams also often pick a constant partition key for convenience and then discover it becomes a hot partition under real traffic. Use time buckets or another sharding dimension when scale matters.
Finally, store timestamps in a format that sorts naturally. If the string order does not match time order, your range queries become unreliable.
Summary
- DynamoDB cannot efficiently query by sort key alone without a partition key value.
- If date-range reads matter, model them with a GSI or synthetic partition key.
- Bucketed date keys are usually safer than one constant partition key.
- A scan with a filter is a fallback, not the primary solution.
- Use ISO 8601 UTC strings so timestamp range queries sort correctly.

