DynamoDB sort keys: query operators and design patterns

Written by Andrea Perera
Last updated: October 23rd, 2026
A DynamoDB sort key orders items that share a partition-key value and, together with that partition key, uniquely identifies each table item. Queries can select a sort-key value, range or prefix using =, <, <=, >, >=, BETWEEN or begins_with. A sort key is optional for a table, but when the schema includes one, every item must provide it.

Sort key vs partition key and range key
The partition key determines the logical collection you query and helps DynamoDB distribute data. The sort key orders records inside that collection. Two items can share either value individually, but not the same complete table primary key.
“Range key” is the older name for sort key. The API still calls it RANGE in KeySchema, while the partition key is HASH. These are names for the same two roles, not additional key types.
For a Book table with BookAuthor as the partition key and BookTitle as the sort key, one author can have many titles. The same title can appear under another author. In an application where authors or titles can collide or change, stable IDs are usually better primary-key components; the title-based example here makes the sorting behavior easy to see.
The keys overview covers schema choices. This page focuses on how to encode and query the sorting dimension.
How DynamoDB sorts key values
| Type | Ordering | Example |
|---|---|---|
| Number | Numeric | 2 precedes 10 |
| String | UTF-8 byte order, case-sensitive | "10" precedes "2"; uppercase and lowercase differ |
| Binary | Unsigned byte order | Compare the decoded bytes, not a displayed base64 string |
Query returns ascending order by default. Set ScanIndexForward: false to reverse it. This changes the order within the queried key collection; it does not sort the whole table or order results by an arbitrary non-key attribute. A Scan does not provide this sort-order guarantee.
String and Binary sort-key values must be nonempty and at most 1,024 bytes. Keys cannot be null, maps, lists, sets or Booleans. For the full type rules, see DynamoDB data types.
Every supported sort-key condition
Every request below also needs partition-key equality, such as #author = :author. The expressions in the table are the optional sort-key part appended with AND.
| Operator | Example condition | Meaning |
|---|---|---|
= | #title = :title | Exactly the supplied title |
< | #title < :title | Titles sorting before the supplied value |
<= | #title <= :title | Titles before or equal to the supplied value |
> | #title > :title | Titles sorting after the supplied value |
>= | #title >= :title | Titles after or equal to the supplied value |
BETWEEN | #title BETWEEN :start AND :end | Inclusive lower and upper bounds |
begins_with | begins_with(#title, :prefix) | String or Binary keys with the specified prefix |
begins_with is case-sensitive and cannot operate on a Number sort key. contains, IN, <> and OR are not supported sort-key conditions in KeyConditionExpression. A base-table sort key takes one of the conditions above; use BETWEEN for two inclusive bounds instead of combining separate inequalities on it. AWS lists the allowed forms in key condition expressions.
A String range from H through S does not include all titles beginning with S. The value "Sapiens" sorts after the exact upper bound "S". Use a prefix for one initial letter, a carefully defined range for your encoding, or a separate normalized attribute/index for the access pattern. Do not assume locale-aware alphabetical matching.
Query by sort key with SDK v3
This AWS SDK for JavaScript v3 example selects an author's books whose titles begin with Harry Potter:
For equality, replace the prefix condition with #title = :title and supply the complete title. If you know both key values and need one table item, GetItem is simpler. A query can omit the sort-key condition entirely to read the author's collection.
Query a sort key in boto3 and the CLI
The same prefix query in boto3:
And with AWS CLI v2:
The CLI uses typed DynamoDB JSON. SDK document interfaces use native language values. Mixing those formats is a common cause of type-validation errors.
Query by sort key only
Query cannot search the base table by sort key alone. It always needs the selected table or index's partition-key value. If you know only a book title, a GSI with BookTitle as its partition key can provide that access path. A scan with a filter also finds matches, but it reads broadly and is unsuitable as the routine lookup path on a large table.
Query with a non-key filter
Use key conditions for BookAuthor and BookTitle, and a filter for a non-key attribute such as BookType:
The filter runs after the matching key range is read. It does not reduce consumed read capacity. If most records are rejected on every request, consider a key or index that represents the required subset directly. See filter expressions for their cost and pagination behavior.
Descending order and pagination
A query evaluates up to 1 MB per page, or the requested Limit number of items, before filtering. A filtered page may contain no items and still have LastEvaluatedKey; continue until the cursor is absent. Limit: 1 with descending order is useful for the largest sort key when there is no filter, but it does not guarantee one returned matching item after filtering.
Add a sort key when creating the table
Declare the sort key when the table is created. Merely adding an attribute named sk to an existing simple-key table does not turn it into a sort key.
Java 2.x Enhanced Client mapping
The Java 1.x DynamoDBMapper annotations have been replaced here with the Java 2.x Enhanced Client. Keep the author's ID stable; automatically generating a new partition key for every book would break author-based grouping.
With that class available, a Java query can use the Enhanced Client's prefix condition:
The Java page iterable retrieves additional pages as you iterate. The mapped class does not modify an existing table's key schema.
Sort-key patterns
Time-ordered records. Store a timestamp as a Number for numeric comparisons, or as a consistent UTC String for time-prefix queries. If two events can share a timestamp, add a stable event ID to the String encoding to prevent a primary-key collision. A month prefix such as EVENT#2026-10- is less error-prone than inventing an end-of-month timestamp.
Hierarchies. A String like COUNTRY#US#STATE#WA#CITY#SEATTLE supports progressively narrower prefixes. Components must be ordered according to how you query them. A city-only lookup needs a different access path. The composite-key guide develops this pattern with related item types.
Revision history. Keep immutable records under versioned sort keys and a separate fixed key for the current version. Update both atomically when the application requires them to agree. Pad String revision numbers if lexical order must match numerical order. This is application-managed history, not automatic DynamoDB versioning.
Alternate orders. An LSI can offer a different sort key under the same partition key and support strong reads, but must exist at table creation and has an item-collection size constraint. A GSI can be added later and can change the partition key too, with eventual consistency. See the index comparison before choosing.
Can you change a sort key?
You cannot add, remove, rename or change the type of a table's sort-key attribute in place. Migrate to a new table for a different primary-key schema. A GSI may satisfy a new query without that migration, but it does not change the table key.
Changing one item's sort-key value does not require a new table. Write the item at its new full primary key and delete the old item. Use a supported transaction and concurrency conditions if the move must be atomic. UpdateItem cannot edit primary-key values directly.
Frequently Asked Questions
Is a sort key required in DynamoDB?
Can I query DynamoDB without a sort-key condition?
Can I query a DynamoDB sort key without a partition key?
How many sort keys can a DynamoDB table have?
Can a DynamoDB sort key be null or empty?
Does BETWEEN include both endpoints?
Dynobase is a Professional GUI Client for DynamoDB
Start your 7-day free trial today
Product Features
DynamoDB Tools
- SSH GUI Client
- Chat With Cloud
- MongoDB GUI Client
- AWS Cost Monitoring
- DynamoDB Query Builder
- DynamoDB Code Examples
- DynamoDB Node.js Queries
- DynamoDB JSON Converter
- DynamoDB UUID Generator
- DynamoDB Local Admin GUI
- DynamoDB Pricing Calculator
- DynamoDB Single-Table Design
- Best DynamoDB GUI Clients
- Dynobase vs DynoTable