Creating a DynamoDB Global Secondary Index to Query Non‑Key Attributes
Learn how to add a GSI so you can query any attribute efficiently, verify it’s active, and understand the cost and performance trade‑offs.
03 Sept 2025, 03:26 UTC

Desired outcome
Add a Global Secondary Index (GSI) to an existing DynamoDB table so you can run low‑latency Query operations on an attribute that is not part of the table’s primary key.
Prerequisites
- AWS CLI version 2 installed and configured with permissions to
dynamodb:UpdateTable,dynamodb:DescribeTable, anddynamodb:Queryon the target table. - The table must be in the
ACTIVEstate. - Decide which attribute(s) will serve as the GSI’s partition key and, optionally, sort key. Ensure those attributes exist in the table items you want to index.
- Estimate the read and write throughput the GSI will need (if using provisioned mode) or be prepared for on‑demand pricing.
Focused procedure
- Identify the table and attribute. Replace
MyTableandemailwith your actual table name and the attribute you want to index. - Create the GSI. Run the following command in a terminal where your AWS credentials are loaded:
aws dynamodb update-table \
--table-name MyTable \
--attribute-definitions AttributeName=email,AttributeType=S \
--global-secondary-index-updates "[{\
'Create': {\
'IndexName': 'EmailIndex',\
'KeySchema': [{\
'AttributeName': 'email',\
'KeyType': 'HASH'\
}],\
'Projection': {'ProjectionType': 'ALL'},\
'ProvisionedThroughput': {\
'ReadCapacityUnits': 5,\
'WriteCapacityUnits': 5\
}\
}\
}]" \
--region us-east-1
Explanation of the command:
--attribute-definitionsdeclares the attribute type for the new index key.- The
--global-secondary-index-updatesblock defines a new GSI namedEmailIndexwithemailas the hash (partition) key, projects all attributes, and sets modest provisioned throughput (adjust these numbers for your workload). - If you prefer on‑demand capacity, replace the
ProvisionedThroughputsection with"BillingMode": "PAY_PER_REQUEST"inside theCreateobject.
- Wait for the index to become active. The update is asynchronous; you can poll the status:
aws dynamodb describe-table --table-name MyTable --query "Table.GlobalSecondaryIndexes[?IndexName=='EmailIndex'].IndexStatus" --output text
Repeat the command until the output shows ACTIVE. While the status is CREATING, queries against the GSI will return a ResourceNotFoundException.
- Validate the GSI with a sample query. Assuming you have an item where
email = "[contact removed]":
aws dynamodb query \
--table-name MyTable \
--index-name EmailIndex \
--key-condition-expression "email = :e" \
--expression-attribute-values '{ ":e": {"S": "[contact removed]"} }' \
--select ALL_ATTRIBUTES \
--region us-east-1
Check the response:
- Items returned should match the expected email value.
- The response includes a
ConsumedCapacityblock; compare theCapacityUnitsto the provisioned read capacity you set (5 RCU in the example). If the consumed units are close to or exceed the provisioned amount, consider increasing the GSI’s read capacity.
Expected checks
- Status check –
describe-tableshowsIndexStatus: ACTIVE. - Query correctness – A
Queryon the GSI returns the expected items without errors. - Capacity monitoring – In CloudWatch, view the metric
ConsumedReadCapacityUnitsfor the GSI (namespaceAWS/DynamoDB, dimensionGlobalSecondaryIndexName=EmailIndex). Ensure it stays below the provisioned read capacity and thatThrottledRequestsremains near zero.
Recovery options (rollback)
Creating a GSI is a state‑changing operation. If you discover the index is unnecessary or causing excessive cost, you can delete it:
aws dynamodb update-table \
--table-name MyTable \
--global-secondary-index-updates "[{\
'Delete': {\
'IndexName': 'EmailIndex'\
}\
}]" \
--region us-east-1
After issuing the delete, monitor describe-table until the index disappears from the GlobalSecondaryIndexes list. Note that deleting a GSI does not affect the base table’s data, but any storage consumed by the index is reclaimed.
Limitations and practical tips
- GSIs use eventual consistency; a read immediately after a write may not reflect the latest value. If you need strong consistency, query the base table instead.
- Each write to the base table incurs additional write capacity units (or request units in on‑demand mode) proportional to the GSI’s key size. High‑write workloads can see increased latency and cost.
- Storage for a GSI grows with the number of indexed items. Large tables with many GSIs can raise storage costs and lengthen backup/restore windows.
- You cannot change the key schema of an existing GSI; to modify it, you must delete and recreate the index.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.