Introduction
Amazon DynamoDB is a powerful, serverless NoSQL database designed for high performance at scale. But with great power comes great complexity especially when it comes to indexes and capacity units.
A DynamoDB table has a primary key (partition key + optional sort key) that defines how data is stored and queried.
But what if you need alternative query patterns ?
In this blog, we’ll break down:
- What are WCU (Write Capacity Units) and RCU (Read Capacity Units) ?
- How to calculate them ?
- Differences between LSI (Local Secondary Index) and GSI (Global Secondary Index).
What are WCU (Write Capacity Unit) and RCU (Read Capacity Unit) ?
DynamoDB operates under two capacity modes :
- Provisioned capacity : You allocate RCUs and WCUs manually, use for Predictable, steady workloads.
- On-demand : AWS handles scaling (costs more per request), use for unpredictable traffic/workloads.
To manage cost and performance effectively, you need to understand RCU (Read Capacity Unit) and WCU (Write Capacity Unit).
WCU – Write Capacity Unit
- 1 WCU = 1 write/sec for an item ≤1 KB.
WCU Formula:
WCUs = ceil(ItemSizeKB / 1KB) × writesPerSecond
Note: Item sizes are always rounded up.
Example: A 4.5 KB item counts as 5 KB → 5 WCUs for 1 write/sec.
RCU – Read Capacity Unit
Read cost depends on item size and read type:
Read Type | ≤4 KB | 4–8 KB | 8–12 KB |
---|---|---|---|
Strongly Consistent Read | 1 RCU | 2 RCUs | 3 RCUs |
Eventually Consistent Read | 0.5 RCU | 1 RCU | 1.5 RCUs |
Transactional Read | 2 RCUs | 4 RCUs | 6 RCUs |
Note: Item sizes are rounded up to the next 4 KB.
Example: A 6 KB item → rounds to 8 KB → 2 RCUs for strong read → 1 RCU for eventual.
RCU Formula:
RCUs = ceil(ItemSizeKB / 4KB) × readsPerSecond
- For strongly consistent reads, multiply by 1.
- For eventually consistent reads, multiply by 0.5.
- For transactional reads, multiply by 2.
Example: Scenario
You expect:
- 100 writes/sec of 2 KB items
- 200 reads/sec of 6 KB items
- Read type = Eventually consistent
Write Capacity:
2 KB item = ceil(2/1) = 2 WCUs
100 writes/sec × 2 WCUs = 200 WCUs
Read Capacity:
6 KB item → round to 8 KB → ceil(8/4) = 2 RCUs (Strongly Consistent)
Eventual read = 2 × 0.5 = 1 RCU
200 reads/sec × 1 RCU = 200 RCUs
Provision at least 200 WCUs and 200 RCUs
Local Secondary Index (LSI) vs Global Secondary Index (GSI)
Secondary indexes let you query your DynamoDB table using alternative keys (not just the primary key).
There are two types LSI (Local Secondary Index) and GSI (Global Secondary Index).
Let’s say we have a table like this:
Partition Key (username) | Sort Key (createdAt) | Role | Region | |
---|---|---|---|---|
alice | 2023-01-01 | alice@example.com | admin | us-east-1 |
bob | 2023-02-05 | bob@example.com | user | eu-west-1 |
Note: A partition in DynamoDB is the physical storage where items are stored.
The partition key decides which partition an item goes to.
Items with the same partition key are grouped together for fast queries.
LSI – Local Secondary Index
An LSI lets you use the same partition key but query using a different sort key.
- Same partition key as the base table, different sort key
- Defined at table creation ONLY
- Supports strongly consistent reads
- Shares throughput and storage with the base table
- Ways to sort or filter data within a partition
- Max 5 LSIs per table
Example
Let’s say we want to sort users within the same username by their role
.
- Primary Key :
username
(PK) +createdAt
(SK) - LSI :
username
(PK) +role
(SK)
Note: LSIs must be defined at table creation and cannot be added later.
GSI – Global Secondary Index
A GSI lets you define a completely different partition key (and optionally a different sort key).
- Different partition and sort keys allowed
- Can be added after table creation
- Eventually consistent reads only
- Has its own RCU/WCU capacity. (GSI writes use the base table’s write capacity during replication. If the base table is saturated, throttling can propagate to GSI writes)
- Max 20 GSIs per table
Example
Let’s say you want to query users by their role
.
- GSI :
role
(PK) +region
(SK)
Note: GSIs can be added any time, but writes are duplicated → extra WCU cost.
LSI vs GSI Comparison
Feature | LSI | GSI |
---|---|---|
Partition Key | Same as table | Different allowed |
Sort Key | Can differ | Can be different or Optional |
Read Consistency | Strong + Eventual | Eventually only |
Provisioning | Shared with base table | Separate RCUs/WCUs |
Query Scope | Within a single partition | Across all partitions |
Define at table creation | Yes | No (can add later) |
Max per table | 5 | 20 |
Use case | Sort/filter within a user | Query by different attribute |
Conclusion
DynamoDB offers unmatched scalability, but designing tables efficiently is key:
- Understand WCU & RCU to avoid throttling and control cost
- Use LSI for alternative sort keys within a partition
- Use GSI for cross-partition queries and new access patterns
Related Docs
Photo by Muhammadh Saamy on Unsplash