GSI vs LSI in DynamoDB: Key Differences and When to Use Each
Global Secondary Index (GSI) allows querying on any attribute with a different partition key and sort key, while a Local Secondary Index (LSI) shares the same partition key as the main table but uses a different sort key. GSIs offer more flexibility and scalability, whereas LSIs are limited to 5 per table and must be created at table creation.Quick Comparison
Here is a quick side-by-side comparison of Global Secondary Index (GSI) and Local Secondary Index (LSI) in DynamoDB.
| Feature | Global Secondary Index (GSI) | Local Secondary Index (LSI) |
|---|---|---|
| Partition Key | Can be different from the base table | Must be the same as the base table |
| Sort Key | Optional and can be different | Optional and must be different from base table's sort key |
| Number per Table | Up to 20 | Up to 5 |
| Creation Time | Can be added anytime | Must be defined at table creation |
| Storage | Stored separately from base table | Stored with base table |
| Consistency | Eventually consistent reads only | Supports strongly consistent reads |
Key Differences
Global Secondary Indexes (GSIs) allow you to query your DynamoDB table using an alternate partition key and optional sort key. They are stored separately from the base table and can be created or deleted anytime after the table is created. GSIs support only eventually consistent reads, which means the data might not be immediately up to date after writes.
In contrast, Local Secondary Indexes (LSIs) share the same partition key as the base table but allow a different sort key. LSIs must be defined when the table is created and cannot be added later. They are stored with the base table data and support strongly consistent reads, which means queries reflect all writes that received a successful response.
GSIs offer more flexibility and scalability because they can have different partition keys and be added anytime, but LSIs provide stronger consistency guarantees and are limited in number and creation time. Choosing between them depends on your query patterns and consistency needs.
Code Comparison
Example of creating a DynamoDB table with a Global Secondary Index (GSI) to query by a different attribute.
import boto3 dynamodb = boto3.client('dynamodb') dynamodb.create_table( TableName='Music', KeySchema=[ {'AttributeName': 'Artist', 'KeyType': 'HASH'}, # Partition key {'AttributeName': 'SongTitle', 'KeyType': 'RANGE'} # Sort key ], AttributeDefinitions=[ {'AttributeName': 'Artist', 'AttributeType': 'S'}, {'AttributeName': 'SongTitle', 'AttributeType': 'S'}, {'AttributeName': 'AlbumTitle', 'AttributeType': 'S'} # For GSI ], ProvisionedThroughput={'ReadCapacityUnits': 5, 'WriteCapacityUnits': 5}, GlobalSecondaryIndexes=[ { 'IndexName': 'AlbumTitleIndex', 'KeySchema': [ {'AttributeName': 'AlbumTitle', 'KeyType': 'HASH'} ], 'Projection': {'ProjectionType': 'ALL'}, 'ProvisionedThroughput': {'ReadCapacityUnits': 5, 'WriteCapacityUnits': 5} } ] )
Local Secondary Index (LSI) Equivalent
Example of creating a DynamoDB table with a Local Secondary Index (LSI) to query by a different sort key but same partition key.
import boto3 dynamodb = boto3.client('dynamodb') dynamodb.create_table( TableName='Music', KeySchema=[ {'AttributeName': 'Artist', 'KeyType': 'HASH'}, # Partition key {'AttributeName': 'SongTitle', 'KeyType': 'RANGE'} # Sort key ], AttributeDefinitions=[ {'AttributeName': 'Artist', 'AttributeType': 'S'}, {'AttributeName': 'SongTitle', 'AttributeType': 'S'}, {'AttributeName': 'AlbumTitle', 'AttributeType': 'S'} # For LSI ], ProvisionedThroughput={'ReadCapacityUnits': 5, 'WriteCapacityUnits': 5}, LocalSecondaryIndexes=[ { 'IndexName': 'AlbumTitleIndex', 'KeySchema': [ {'AttributeName': 'Artist', 'KeyType': 'HASH'}, # Same partition key {'AttributeName': 'AlbumTitle', 'KeyType': 'RANGE'} # Different sort key ], 'Projection': {'ProjectionType': 'ALL'} } ] )
When to Use Which
Choose a Global Secondary Index (GSI) when you need to query your data using a different partition key than the base table or want to add indexes after table creation. GSIs are best for flexible query patterns and scaling read capacity independently.
Choose a Local Secondary Index (LSI) when you want to query using the same partition key but a different sort key, and you need strongly consistent reads. LSIs must be planned at table creation and are limited in number, so use them when your query patterns are well-defined and consistency is critical.