When to Use DynamoDB GSIs vs LSIs: Real World Examples
Deep dive into trade-offs and real use cases.
DynamoDB can be confusing.
Indexes are one of these concepts which at first make no sense.
But once you get it, GSIs are an irreplaceable tool that you will you use multiple times in any DynamoDB workload.
But indexes are completely different from indexes in SQL. They have no similarities and this is what confuses new DynamoDB users.
So what are secondary indexes?
DynamoDB offers two types of secondary indexes:
Global Secondary Indexes (GSIs)
Local Secondary Indexes (LSIs)
Both help you support additional access patterns beyond your primary. But they come with different capabilities and trade-offs.
In this post, I’ll break down the differences, explore real-world use cases, and help you decide when to use each.
Basics of GSI vs LSI
Global Secondary Indexes have the following features:
They can have a different partition key and sort key from the base table.
are eventually consistent by default.
Have their own read/write throughput limits.
You can create up to 20 GSIs per table
Local Secondary Indexes have the following features:
They use the same partition key as the base table, but a different sort key.
They are strongly consistent.
They share provisioned throughput and storage with the base table.
You are limited to 5 LSIs per table
You have to create them at table creation time, and cannot create them afterwards.
When to Use a GSI
Some use cases when you should use a GSI:
1. Different Partition Key queries
Let’s say your primary table is structured like this:
PK: user#101
SK: order#2024–01–01
But you also want to fetch all orders by status:
“Show me all orders with status = PENDING”
You can’t do this with an LSI since the partition key (USER#123) is fixed. You’d create a GSI with:
GSI1PK: status#PENDING
GSI1SK: timestamp
Now, querying all pending orders is easy.
2. Model Cross Entity Relationships
Imagine you want to model likes on posts. You might use a GSI like:
PK: post#201
SK: user#101
GSI1PK: user#101
GSI1SK: post#201
This lets you query:
All likes on a post (PK: post#201)
All posts liked by a user (GSI1PK: user#101)
GSIs give you flexibility LSIs can’t when access patterns span multiple types of entities.
3. Adding indexes after table creation
A key limitation of LSIs is that they must be defined at the moment you create your table.
If you want to support a new query down the line, GSIs are your only option.
When to Use an LSI
Some use cases when you should use a LSI:
1. Strong consistency requirements
LSIs support strongly consistent reads, while GSIs are eventually consistent.
If your app can’t tolerate stale data, for example, banking transactions or order fulfillment processes, then LSIs are a safer bet.
2. Sorting data differently within the same partition
Imagine this table layout:
PK: customer#101
SK: invoice#<timestamp>
You want to also query invoices by amount instead of timestamp. You can define an LSI with:
LSI1SK: amount
Now, you can run queries like:
Give me all invoices for customer#101 sorted by amount.
Since the partition key is unchanged, LSIs are efficient in this scenario.
3. Save on costs
Because LSIs share storage and throughput with the base table, they can be more cost-efficient than GSIs, especially if your access pattern volume is low.
Trade-Offs Summary
Conclusion
DynamoDB indexing is powerful but doesn’t offer limitless flexibility and so understanding each type is essential.
Use LSIs when you need strongly consistent, same-partition queries with different sort orders. Use GSIs when you need flexible, scalable, cross-entity access patterns or when designing after table creation.
Your access patterns determine your index strategy, not the other way around. Think backwards from your app’s query needs, and the right choice will be easier to make.
👋 My name is Uriel Bitton and I’m committed to helping you master Serverless, Cloud Computing, and AWS.
🚀 If you want to learn how to build serverless, scalable, and resilient applications, you can also follow me on Linkedin for valuable daily posts.
Thanks for reading and see you in the next one!