0
0
DynamodbComparisonBeginner · 4 min read

GSI vs LSI in DynamoDB: Key Differences and When to Use Each

In DynamoDB, a 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.

FeatureGlobal Secondary Index (GSI)Local Secondary Index (LSI)
Partition KeyCan be different from the base tableMust be the same as the base table
Sort KeyOptional and can be differentOptional and must be different from base table's sort key
Number per TableUp to 20Up to 5
Creation TimeCan be added anytimeMust be defined at table creation
StorageStored separately from base tableStored with base table
ConsistencyEventually consistent reads onlySupports 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.

python
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}
        }
    ]
)
Output
Creates a DynamoDB table named 'Music' with a GSI named 'AlbumTitleIndex' allowing queries by 'AlbumTitle'.
↔️

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.

python
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'}
        }
    ]
)
Output
Creates a DynamoDB table named 'Music' with an LSI named 'AlbumTitleIndex' allowing queries by 'AlbumTitle' with the same 'Artist' partition key.
🎯

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.

Key Takeaways

GSIs allow different partition keys and can be added anytime, offering flexible queries.
LSIs share the base table's partition key but use a different sort key and support strong consistency.
GSIs are stored separately and support only eventually consistent reads.
LSIs must be created with the table and are limited to 5 per table.
Use GSIs for flexible, scalable queries; use LSIs for consistent queries on the same partition key.