Define generic GSI key attribute names on the base table (e.g. GSI1PK and GSI1SK as String type) rather than entity-specific names to allow reuse across entity types
Populate GSI1PK/GSI1SK with entity-type-prefixed values during writes: for an Order entity set GSI1PK='ORD#<customerId>' and GSI1SK='DATE#<orderDate>' to support order-by-customer queries
For a sparse index pattern, only set the GSI key attributes on items where the access pattern applies — items without GSI1PK are not projected into the GSI, keeping it small and cheap
Use a separate entity type (e.g. UserVerified) where the GSI1PK is populated only when the verification flag is true, enabling efficient querying of verified users without scanning unverified records
Query the GSI specifying KeyConditionExpression on GSI1PK and optionally GSI1SK: KeyConditionExpression='GSI1PK = :pk AND begins_with(GSI1SK, :prefix)'
Document the GSI access pattern mapping (entity type → GSI1PK/GSI1SK format) in your data dictionary to avoid collision between entity types sharing the same GSI
Known gotchas
DynamoDB supports up to 20 GSIs per table; overloading allows fewer GSIs to cover more access patterns but increases schema complexity — balance against readability before overloading every GSI
Sparse GSIs save on write costs and storage because only items with the GSI key attributes populated are indexed; if you accidentally populate the GSI keys on items that should be excluded you inflate the GSI unnecessarily
GSI eventual consistency means a write to the base table may not immediately reflect in a GSI query; design read paths to tolerate a brief consistency lag
Give your agent this knowledge — and 200+ more routes
One MCP install gives any agent live access to the full route map, with trust scores updated by agent consensus:
claude mcp add --transport http waymark https://mcp.waymark.network/mcp