DynamoDB GSI vs LSI: How Secondary Indexes Differ
Definition
DynamoDB lets you query items by their primary key — the partition key (and optional sort key). To query by other attributes efficiently, you add a secondary index, which is a materialized alternate view of the table.
There are two kinds:
- Global Secondary Index (GSI) — a different partition key than the base table. Eventually consistent; independent throughput; can be added or dropped at any time. Up to 20 per table.
- Local Secondary Index (LSI) — the same partition key but a different sort key. Supports strong consistency; shares table throughput; must be defined at creation. Up to 5 per table.
Picking the right one is a frequent exam question and a real-world design decision with long-term consequences.
How It Works
When you create a secondary index, DynamoDB maintains a separate, indexed copy of selected attributes from the base table. Writes to the base table propagate to the index automatically.
GSI
- Internally a separate DynamoDB table, partitioned by the GSI's own partition key.
- Because the partition key differs, replication is asynchronous — reads are eventually consistent.
- Can be added, modified, or deleted on an existing table.
- Has its own RCU/WCU in provisioned mode; scales independently in On-Demand.
- Projection types:
KEYS_ONLY,INCLUDE,ALL.
LSI
- Shares the base table's partition (same partition key, different sort key).
- Supports strongly consistent reads because the base item and index entry are updated together.
- Must be created at table creation time — cannot be added or dropped later.
- Shares the base table's provisioned throughput.
Key Features and Limits
GSI vs LSI at a glance
| | GSI | LSI | | --- | --- | --- | | Partition key | Different from base table | Same as base table | | Sort key | Optional, any attribute | Required, different from base | | Consistency | Eventually consistent only | Eventual or strong | | Creation time | Any time — add/drop later | Table creation only | | Max per table | 20 | 5 | | Throughput | Independent RCU/WCU | Shared with base table | | Partition size limit | None | 10 GB per partition-key value |
Item collection size limit (LSI gotcha)
When a table has LSIs, the total size of all items with a given partition-key value — across the base table and all its LSIs — cannot exceed 10 GB. Hitting this limit returns ItemCollectionSizeLimitExceededException and requires data model refactoring. GSIs are not subject to this cap because they live in separate partitions.
Consistency semantics
- GSI reads: eventually consistent (typical lag: milliseconds).
ConsistentRead=trueis not supported on GSIs. - LSI reads: default eventual, but
ConsistentRead=trueis supported (consumes 2× the RCU of an eventual read, same as base-table strong reads).
Write amplification
Every write to the base table is replicated to each index where the indexed attributes appear. Five GSIs plus one LSI means up to six write operations, each consuming capacity.
Common Use Cases
Pick a GSI when…
- You need to query by an entirely different attribute (e.g., query users by
emailwhen the base table's partition key isuser_id). - Access patterns emerged after the table was created.
- You want independent throughput for a hot query path.
- Cross-partition queries and listings are a primary access pattern.
Pick an LSI when…
- You want alternate sort orders within the same partition — for example, items for a given user sorted by
created_atin the base table and bypriorityin an LSI. - You need strongly consistent reads on the alternate sort key.
- You can define the access pattern upfront at table creation, and total data per partition key stays under 10 GB.
Pricing Model
- GSI: in Provisioned mode, you pay for the GSI's own RCU/WCU plus storage. In On-Demand mode, you pay per GSI request. Both modes charge for storage consumed by the indexed attributes.
- LSI: no separate throughput bill — LSI reads and writes draw from the base table's RCU/WCU (or On-Demand capacity). You still pay for the extra storage consumed by the LSI.
In both cases, projection type matters: KEYS_ONLY stores only the primary key attributes (cheapest); INCLUDE adds a selected list; ALL copies every attribute (most convenient, most expensive). Right-size your projections for real query needs to keep costs down.
Pros and Cons
GSI
Pros: add/drop any time, independent throughput, up to 20 per table, no 10 GB partition cap, enables any alternate access pattern.
Cons: eventually consistent only, extra write cost, storage overhead, may hide modeling mistakes (too many GSIs = smell).
LSI
Pros: strong consistency available, no separate throughput to manage, simpler mental model for same-partition range queries.
Cons: fixed at table creation, 5-per-table limit, 10 GB item-collection cap can be a trap, cannot be dropped later.
Comparison with Alternatives
| | GSI | LSI | Extra base table | | --- | --- | --- | --- | | Cost | Storage + independent capacity | Storage only | Full duplicate cost | | Consistency | Eventual | Strong or eventual | Depends on your sync | | Flexibility | High — add any time | Low — creation only | Total control | | Operational overhead | Low | Low | You maintain sync |
For most workloads, GSIs are the right tool. LSIs are a precision instrument for same-partition alternate sort orders with strong consistency.
Exam Relevance
- Solutions Architect Associate (SAA-C03) — the LSI vs GSI decision comes up in nearly every DynamoDB question set. Watch for keywords: "different partition key" or "add later" → GSI; "different sort key", "same partition", "strong consistency" → LSI.
- Developer Associate (DVA-C02) — creating and using secondary indexes; projection types; cost implications of
ALLprojection; consistent-read support. - Database Specialty (DBS-C01) — deep data-modeling questions, item collection size limits, cost optimization, when to refactor rather than add another index.
Exam trap: "must exist at table creation" → LSI. "query by a completely different attribute" → GSI. "strong consistency and alternate sort order" → LSI. "up to 20 indexes" → GSI.
Frequently Asked Questions
Q: Can I add or remove a Local Secondary Index on an existing table?
A: No. LSIs must be defined at table creation and cannot be added, modified, or removed later. If you need a new alternate sort key on an existing table, your options are: add a GSI (which can be added any time, though with only eventual consistency), create a new table with the desired LSIs and migrate data, or use DynamoDB Streams + Lambda to maintain a derived table. GSIs, by contrast, can be added or dropped at any time with an online backfill and no downtime.
Q: Why does DynamoDB enforce a 10 GB limit on LSI item collections?
A: Because an LSI shares the same partition as its base table's items, all items with a given partition-key value — plus their LSI entries — must fit on the same physical partition (up to 10 GB). This enables the strong-consistency semantics LSIs offer. GSIs have no such limit because the GSI is an independently partitioned structure. If you expect a single partition key to accumulate more than 10 GB of items plus LSIs, either drop the LSI, move to a GSI, or redesign the partition key for higher cardinality.
Q: Which is cheaper, GSI or LSI?
A: LSIs have no separate throughput bill — they share the base table's RCU/WCU or On-Demand capacity — so a moderately sized LSI can be cheaper than an equivalent GSI with its own provisioned throughput. However, LSIs still consume storage, and they amplify the table's write capacity consumption. GSIs scale throughput independently, which can be either cheaper (when the GSI is queried far less than the base table) or more expensive (when the GSI needs its own high capacity). Model both scenarios with your actual read/write mix before choosing.
This article reflects AWS features and pricing as of 2026. AWS services evolve rapidly — always verify against the official Amazon DynamoDB documentation before making production decisions.