DynamoDB keys, indexes and consistency: DVA-C03 study notes and practice questions
What to know about DynamoDB keys, indexes and consistency for the DVA-C03 exam, from the Development with AWS Services domain (30% of the exam guide), then 2 free questions to test it. Part of the DVA-C03 study guide.
Key questions give you a table, a query the app must run, and a symptom such as throttling, stale reads or overwritten data. The fix is almost always in the keys, the index or the write condition.
Keys
The partition key decides which partition stores an item. The sort key orders items with the same partition key and lets you query a range.
A hot key sends most traffic to one partition value, so writes throttle even when the table has spare capacity. A date such as 2026-10-15 as the only partition key is a common example. Fix it with a higher-cardinality key or write sharding.
You can’t query by a non-key attribute on the base table without a Scan. Add an index instead.
Secondary indexes
Index
Keys
When created
Consistency
Global secondary index (GSI)
Any partition and sort key
Any time
Eventually consistent only
Local secondary index (LSI)
Same partition key, different sort key
Only when the table is created
Strongly consistent reads are allowed
An index is sparse if items lack its key attributes. Setting a flag attribute only on items that need review gives a small, cheap index.
A GSI read can return a value from before the latest write. A checkout that re-reads an order’s status from a GSI can see the old status. Read the base table with a strongly consistent GetItem instead.
Safe writes
A plain PutItem silently replaces an existing item. Add a condition expression such as attribute_not_exists on the partition key so the write fails when the item already exists.
For optimistic locking, keep a version attribute, check it in a condition expression, and increment it on each write. A failed condition means someone else changed the item.
Time to live
TTL deletes expired items. The TTL attribute must hold a Number holding an epoch timestamp in seconds. An ISO 8601 text string is ignored.
TTL deletion happens in the background, so expired items can remain for a while.
Common traps
Adding a GSI to fix a bad base key. Changing the table’s key usually means a new table and a migration.
Expecting an LSI on an existing table. LSIs can only be created with the table.
Using a GSI for a read that must be current.
Plain PutItem for uniqueness. Use a condition expression.
A ticket-booking app stores tickets in a DynamoDB table named Tickets, with TicketId as the partition key.
The table has been in production for two years and holds 40 million items. Support staff must find every ticket for a given email address, and the lookup must not scan the table. The change must not rebuild the table.
What should the developer do?
Choose one answer.
AA. Add a local secondary index with EmailAddress as its partition key.
BB. Run a Scan with a FilterExpression on EmailAddress for each support lookup.
CC. Add a global secondary index keyed on EmailAddress, and query it by email.
DD. Change the table's partition key to EmailAddress by calling UpdateTable on the table.
Show the answer and explanation
Answer: C
A. Wrong: A local secondary index must use the table's partition key, which here is TicketId. It also has to be created with the table, so it cannot be added to this table now.
B. Wrong: A scan reads the whole table and filters the results afterwards. It becomes slower and more costly as the table grows, which the team wants to avoid.
D. Wrong: A table's primary key cannot be changed after creation. A new table would have to be created and the data migrated into it.
Explanation
A global secondary index can have its own partition key, which can be any scalar attribute, and it can be added to a table that is already in production. A local secondary index shares the table partition key and must be created with the table. A query on the new index replaces the scan.
A checkout service writes an order with PutItem and then reads the order's status through a global secondary index on a status attribute, to confirm the write before it replies to the customer.
Sometimes the status returned is the previous one, so customers see an order that appears unconfirmed. The confirmation must always reflect the completed write.
What should the developer change?
Choose one answer.
AA. Read the order from the base table with GetItem, and set ConsistentRead to true.
BB. Keep the query on the index, and add a short sleep between the write and the query so that the index can catch up.
CC. Wrap the PutItem and the query in a single TransactWriteItems request.
DD. Run a Scan of the same index with ConsistentRead set to true.
Show the answer and explanation
Answer: A
A. Right: Correct. A strongly consistent read on the base table reflects all prior successful writes. Strongly consistent reads are supported on tables and local secondary indexes, but not on global secondary indexes.
B. Wrong: A delay makes a stale read less likely but does not guarantee a fresh one. It also adds latency to every checkout.
C. Wrong: TransactWriteItems groups write actions. It cannot return the data that a query reads, and it does not make index reads strongly consistent.
D. Wrong: Strongly consistent reads are not available on a global secondary index. A scan of the index can still return the old status.
Explanation
Reads from a global secondary index are always eventually consistent, so the index can briefly return an older status after a write. Reading the item from the base table with ConsistentRead set to true returns the latest committed data, at twice the read cost of an eventually consistent read.
Want more on DynamoDB keys, indexes and consistency? The 5 full-length practice sets have 7 more DynamoDB keys, indexes and consistency questions, 390 in all, none of them in the free exam. One payment of $14.99, no subscription. See the practice sets →