Using DynamoDB Global Secondary Indexes to Query Non‑Key Attributes
Learn how to add a Global Secondary Index to a DynamoDB table so you can query any attribute, see a CLI example, and understand the limits and pitfalls.
21 Apr 2026, 11:34 UTC

If you need to look up items by an attribute that isn’t part of the table’s primary key, create a Global Secondary Index (GSI). A GSI maintains a separate copy of the selected attributes plus the base table’s primary key, letting you query that attribute with eventual consistency.
How a GSI works
When you write an item to the base table, DynamoDB asynchronously updates any GSIs you defined. The index stores only the attributes you chose to project (or the full item if you select ALL) and the hash/sort key of the index. Queries against a GSI use the index’s key schema and return the projected attributes; they are eventually consistent, typically replicating within a second.
Example: creating a table with a GSI
# Replace placeholders with your own values
# Required IAM permissions: dynamodb:CreateTable, dynamodb:PutItem, dynamodb:Query
# Runs in your local AWS CLI environment
aws dynamodb create-table \
--table-name Orders \
--attribute-definitions \
AttributeName=OrderID,AttributeType=S \
AttributeName=CustomerID,AttributeType=S \
--key-schema AttributeName=OrderID,KeyType=HASH \
--global-secondary-indexes \
IndexName=CustomerIndex,\
KeySchema=[{AttributeName=CustomerID,KeyType=HASH}],\n Projection={ProjectionType=ALL},\n ProvisionedThroughput={ReadCapacityUnits=5,WriteCapacityUnits=5} \
--billing-mode PROVISIONED
Inserting an item
aws dynamodb put-item \
--table-name Orders \
--item '{"OrderID":{"S":"order123"},"CustomerID":{"S":"alice"},"Amount":{"N":"42"}}'
Querying the GSI
aws dynamodb query \
--table-name Orders \
--index-name CustomerIndex \
--key-condition-expression 'CustomerID = :v' \
--expression-attribute-values '{':v':{'S':'alice'}}'
The response will include the item you just inserted, showing that the GSI can be used to find orders by customer ID.
Limits
- Maximum of 20 GSIs per table.
- Each GSI can project at most the full item size (400 KB).
- GSIs consume read/write capacity from the table (or separate capacity if the table uses on‑demand mode).
- Queries are eventually consistent; typical replication lag is under one second.
Common mistakes
- Omitting the Projection parameter. Without it the index defaults to KEYS_ONLY, which may lack the attributes you need to return.
- Over‑provisioning capacity. If the provisioned read/write units are too low, the GSI will throttle and return ProvisionedThroughputExceededException.
- Assuming strong consistency. GSIs only support eventual consistency; designs that require immediate visibility must handle stale reads or use retry/back‑off.
- Creating GSIs on high‑cardinality keys. A very popular hash key (e.g., a status field with few values) can create hot partitions in the index, causing throttling.
Verification
- After creating the table and inserting an item, run the query command above and confirm the item appears in the result set.
- Check CloudWatch metrics for the index:
OnlineIndexConsumedWriteCapacityUnits(write throughput) andIndexSizeBytes(storage usage). Ensure values stay within your provisioned limits and expected storage costs. - If you see throttling, adjust the GSI’s provisioned throughput or switch the table to on‑demand mode.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.