Top 60 DynamoDB Interview Questions (2026)

The 60 DynamoDB questions interviewers actually ask, with direct answers, runnable code, and what the interviewer is listening for. Grouped for freshers, intermediate, and experienced rounds.

60 questions with answers

What Is DynamoDB?

Key Takeaways

  • DynamoDB is a fully managed, serverless, key-value and document NoSQL database from AWS with single-digit millisecond latency at any scale.
  • You design the table around your access patterns first, because DynamoDB rewards known query shapes and punishes ad-hoc queries.
  • Interviews test data modeling (partition keys, sort keys, indexes) and the runtime model (capacity, partitions, consistency), not memorized API names.
  • This page is a question bank: work your tier first, read one tier up, and say answers out loud because delivery is evaluated too.

DynamoDB is a fully managed NoSQL database service from AWS that stores data as key-value and document items and returns them with single-digit millisecond latency at almost any scale. It's serverless: there are no servers to patch, no replication to configure, and throughput scales up or down without downtime. Data lives in tables, every item is found by a primary key, and the database spreads items across partitions by hashing that key. In interviews, DynamoDB questions probe how you model data around access patterns and how the runtime behaves under load (capacity modes, partition limits, consistency choices), not trivia about method names. According to the Amazon DynamoDB Developer Guide, you should list your application's read and write patterns before you design a table, because the schema follows the queries rather than the other way around. This page collects the 60 questions that come up most, each with a direct answer and runnable code. Increasingly the first technical round is a live AI coding interview, so pair this bank with our AI interview preparation guides for the format side.

60Questions with answers on this page
3Difficulty tiers: freshers, intermediate, experienced
22Runnable code snippets you can practice from
45-60 minTypical length of a DynamoDB technical round

Watch: AWS re:Invent 2018: Amazon DynamoDB Deep Dive: Advanced Design Patterns for DynamoDB (DAT401)

Video: AWS re:Invent 2018: Amazon DynamoDB Deep Dive: Advanced Design Patterns for DynamoDB (DAT401) (Amazon Web Services, YouTube)

Test yourself and earn a certificate

10 quick questions. Score 70%+ to download your DynamoDB certificate.

Jump to quiz

All Questions on This Page

60 questions
DynamoDB Interview Questions for Freshers
  1. 1. What is DynamoDB and what problem does it solve?
  2. 2. How is DynamoDB different from a relational database?
  3. 3. What are the two types of primary key in DynamoDB?
  4. 4. What does the partition key do?
  5. 5. What is a sort key and why is it useful?
  6. 6. What is the difference between Query and Scan?
  7. 7. What is the difference between strongly and eventually consistent reads?
  8. 8. What are items and attributes in DynamoDB?
  9. 9. What data types does DynamoDB support?
  10. 10. How do you write and read a single item?
  11. 11. How does UpdateItem differ from PutItem?
  12. 12. What are the two capacity modes?
  13. 13. What are RCUs and WCUs?
  14. 14. What happens when you exceed provisioned throughput?
  15. 15. What is a Global Secondary Index (GSI)?
  16. 16. What is a Local Secondary Index (LSI)?
  17. 17. What do BatchGetItem and BatchWriteItem do?
  18. 18. Why do you sometimes need expression attribute names?
  19. 19. What is the maximum item size, and how do you store larger data?
  20. 20. What is Time to Live (TTL) in DynamoDB?
DynamoDB Intermediate Interview Questions
  1. 21. What is single-table design and why do people use it?
  2. 22. Why is DynamoDB modeling described as access-pattern driven?
  3. 23. What is a hot partition and how do you avoid it?
  4. 24. When do you choose a GSI over an LSI?
  5. 25. What are GSI projection types and why do they matter?
  6. 26. What are conditional writes and what do they prevent?
  7. 27. How do DynamoDB transactions work?
  8. 28. What are DynamoDB Streams and what are they used for?
  9. 29. What is DynamoDB Accelerator (DAX)?
  10. 30. How does pagination work in Query and Scan?
  11. 31. What is adaptive capacity?
  12. 32. What is an overloaded GSI (GSI overloading)?
  13. 33. What is a sparse index and when is it useful?
  14. 34. How do you calculate capacity for a workload?
  15. 35. How should an application handle DynamoDB errors?
  16. 36. What backup and recovery options does DynamoDB offer?
  17. 37. What are DynamoDB global tables?
  18. 38. Why doesn't a FilterExpression save read capacity?
  19. 39. How many indexes can a table have, and why does it matter?
  20. 40. How do you develop and test against DynamoDB locally?
DynamoDB Interview Questions for Experienced Engineers
  1. 41. How does DynamoDB partition data internally?
  2. 42. How do you model a many-to-many relationship in DynamoDB?
  3. 43. How does DynamoDB achieve durability and its consistency guarantees?
  4. 44. How do you optimize DynamoDB cost on a large table?
  5. 45. A single item is getting hammered and throttling. Walk through your options.
  6. 46. How do you build reliable processing on DynamoDB Streams?
  7. 47. How would you migrate a relational table to DynamoDB?
  8. 48. Explain write sharding and its read-side cost.
  9. 49. Can a GSI throttle the base table, and how?
  10. 50. How do you handle items that approach or exceed 400 KB?
  11. 51. How do you implement optimistic locking in DynamoDB?
  12. 52. How do you model time-series data in DynamoDB?
  13. 53. How do you design an app around eventual consistency?
  14. 54. How does DynamoDB compare to Cassandra, and when would you pick each?
  15. 55. What DynamoDB metrics do you monitor in production?
  16. 56. Design question: use DynamoDB for a URL shortener at scale.
  17. 57. You inherited a table that relies on Scans. How do you fix it?
  18. 58. How do you design a multi-tenant application on DynamoDB?
  19. 59. What operational limits and gotchas surprise teams in production?
  20. 60. When would you argue against using DynamoDB?

DynamoDB Interview Questions for Freshers

Freshers20 questions

The fundamentals every entry-level round checks. If any answer here surprises you, that's your study list.

Q1. What is DynamoDB and what problem does it solve?

DynamoDB is a fully managed NoSQL database from AWS that stores key-value and document data and returns it with single-digit millisecond latency at almost any scale. It's serverless, so there's no cluster to run, patch, or replicate.

It solves the problem of predictable performance under unpredictable load. You get consistent latency whether the table holds a thousand items or a billion, and throughput scales without downtime. The cost is that you design around known access patterns instead of running ad-hoc queries.

Key point: A one-line definition plus the trade-off (managed and fast, but access-pattern driven) beats a feature list. Interviewers open with this to hear how you frame a database.

Watch a deeper explanation

Video: DynamoDB in 20 Minutes: Intro to NoSQL (Caleb Curry, YouTube)

Q2. How is DynamoDB different from a relational database?

A relational database organizes data into tables with fixed schemas and lets you join and query freely with SQL. DynamoDB stores schemaless items, has no joins, and is built to serve a known set of access patterns fast.

The mental shift is that you model for the query in DynamoDB. Instead of normalizing and joining at read time, you shape the data so the reads you need are single, cheap lookups.

Relational DBDynamoDB
SchemaFixed, enforcedFlexible per item
JoinsYesNo (denormalize instead)
ScalingVertical, then shardingHorizontal, automatic
Query styleAd-hoc SQLAccess-pattern driven

Key point: The follow-up is usually 'when would you pick one over the other?'. Have a concrete example ready: user sessions or a shopping cart for DynamoDB, financial reporting for relational.

Q3. What are the two types of primary key in DynamoDB?

A simple primary key is just a partition key (also called a hash key). A composite primary key is a partition key plus a sort key (also called a range key).

With a simple key, each item is found by one value. With a composite key, many items can share a partition key and are stored together, sorted by the sort key, which is what makes range queries within a partition efficient.

json
// Simple key: one partition key
{ "userId": "u#42" }

// Composite key: partition key + sort key
{ "userId": "u#42", "orderId": "2026-07-04#001" }

Q4. What does the partition key do?

DynamoDB hashes the partition key value and uses the result to decide which physical partition stores the item. All reads and writes for that item route to the same partition.

That's why partition key choice matters so much: if many requests target the same key value, they all hit one partition and you get throttling. Spreading traffic across many distinct key values keeps load balanced.

Key point: Interviewers use this to set up the hot-partition question later. even distribution here matters.

Q5. What is a sort key and why is it useful?

A sort key orders items that share a partition key. Within one partition key, items are stored sorted by the sort key, so you can fetch ranges: all orders for a user between two dates, the latest N events, everything with a given prefix.

Sort keys are where a lot of modeling power lives. Prefixing sort key values (like ORDER#2026 or PROFILE#) lets one table hold different item types under the same partition key and query them selectively.

python
from boto3.dynamodb.conditions import Key

# All orders for a user in July 2026
resp = table.query(
    KeyConditionExpression=Key("userId").eq("u#42")
    & Key("orderId").begins_with("2026-07")
)

Q6. What is the difference between Query and Scan?

Query fetches items for a specific partition key, optionally narrowed by a sort key condition. It only reads matching items, so it's fast and cheap. Scan reads every item in the table and then applies filters, so it gets slower and more expensive as the table grows.

The rule in interviews: design so you Query, and treat Scan as a smell. A filter expression on a Scan still charges you for every item read, not just the ones returned.

python
from boto3.dynamodb.conditions import Key

# Good: Query by partition key
table.query(KeyConditionExpression=Key("userId").eq("u#42"))

# Avoid: Scan reads the whole table, filter runs after
table.scan(FilterExpression=Attr("status").eq("active"))

Reading 10,000 items: Query one partition vs Scan the table

Items DynamoDB reads and charges for. Query targets one partition key; Scan reads every item then filters.

Query (one partition)
50 items read
Scan + filter
10,000 items read
  • Query (one partition): Reads only matching items for the key
  • Scan + filter: Reads all items, filters after, charges for all

Key point: Saying 'a FilterExpression doesn't reduce read cost, it only reduces what comes back' is the detail that separates a real answer from a memorized one.

Q7. What is the difference between strongly and eventually consistent reads?

A strongly consistent read returns the most recent data, reflecting every successful write before it. An eventually consistent read might return slightly stale data because it can be served from a replica that hasn't caught up yet, usually within a second.

Eventually consistent reads are the default and cost half as much. Ask for strong consistency only when reading your own recent write matters, like showing a value the user just saved.

python
# Strongly consistent read costs 2x an eventually consistent one
table.get_item(
    Key={"userId": "u#42"},
    ConsistentRead=True,
)

Key point: The trap is claiming strong consistency is always better. Naming the 2x cost and the eventual-consistency default shows you understand the trade-off.

Q8. What are items and attributes in DynamoDB?

An item is a single record, like a row. An attribute is a name-value pair inside an item, like a column value. Every item must have the table's primary key attributes; everything else is optional and can differ item to item.

This is the schemaless part: two items in the same table can hold completely different attributes as long as both carry the primary key. That flexibility is what makes single-table designs possible.

Q9. What data types does DynamoDB support?

Scalars: string (S), number (N), binary (B), boolean (BOOL), and null (NULL). Documents: list (L) and map (M) for nested structures. Sets: string set (SS), number set (NS), and binary set (BS) for unique collections.

Numbers are stored as a single type with high precision, so there's no separate int and float. Sets can't be empty and can't hold duplicates, which trips people up when they expect list behavior.

Q10. How do you write and read a single item?

PutItem writes or fully replaces an item by primary key. GetItem reads one item by its full primary key. Both are the cheapest, fastest operations because they touch exactly one item on one partition.

PutItem overwrites the whole item if the key already exists. To change only some attributes, use UpdateItem instead, which modifies named attributes without replacing the rest.

python
table.put_item(Item={
    "userId": "u#42",
    "name": "Asha",
    "plan": "pro",
})

resp = table.get_item(Key={"userId": "u#42"})
item = resp.get("Item")

Q11. How does UpdateItem differ from PutItem?

UpdateItem changes named attributes on an existing item and leaves the rest untouched; it creates the item if it doesn't exist. PutItem replaces the entire item, dropping any attributes you didn't include.

UpdateItem also does atomic operations in place: incrementing a counter, adding to a set, appending to a list, all without reading first. That avoids a read-modify-write race.

python
table.update_item(
    Key={"userId": "u#42"},
    UpdateExpression="SET plan = :p ADD loginCount :one",
    ExpressionAttributeValues={":p": "enterprise", ":one": 1},
)

Q12. What are the two capacity modes?

Provisioned mode has you set read capacity units and write capacity units up front; you pay for that reserved throughput whether you use it or not, and it's cheaper for steady, predictable load. On-demand mode charges per request with no planning and scales instantly, which fits spiky or new workloads.

A common answer: start on-demand while traffic is unknown, then switch to provisioned with auto scaling once the pattern is clear and you want lower cost.

ProvisionedOn-demand
You set capacityYes (RCU/WCU)No
BillingPer provisioned capacityPer request
Best forSteady, predictable loadSpiky or unknown load
Throttling riskIf you under-provisionRare, scales automatically

Q13. What are RCUs and WCUs?

A Read Capacity Unit is one strongly consistent read per second of an item up to 4 KB, or two eventually consistent reads. A Write Capacity Unit is one write per second of an item up to 1 KB. Bigger items consume more units, rounded up.

So a 10 KB item costs 3 RCUs for a strongly consistent read (10 KB rounds to 3 blocks of 4 KB) and 10 WCUs to write. Knowing the rounding is what interviewers check.

Key point: The exact numbers matter: 4 KB per read unit, 1 KB per write unit, rounded up. Getting the units right signals you've actually sized a table.

Q14. What happens when you exceed provisioned throughput?

DynamoDB throttles the request and returns a ProvisionedThroughputExceededException. The AWS SDKs catch that and retry the throttled request automatically with exponential backoff and jitter, so short spikes usually recover on their own and your application never sees an error surface.

Sustained throttling means you're under-provisioned or you have a hot partition sending too much traffic to one key. The fix is more capacity, auto scaling, or a better-distributed partition key.

Q15. What is a Global Secondary Index (GSI)?

A GSI is an index with its own partition key and optional sort key, different from the base table's keys. It lets you query by attributes that aren't the primary key. DynamoDB keeps the index in sync automatically as the base table changes.

GSIs are always eventually consistent and have their own capacity. You choose which attributes get projected into the index, which controls its size and whether reads need to fetch back from the base table.

python
# Query a GSI named "email-index" by email
table.query(
    IndexName="email-index",
    KeyConditionExpression=Key("email").eq("asha@example.com"),
)

Q16. What is a Local Secondary Index (LSI)?

An LSI shares the base table's partition key but uses a different sort key, giving you an alternate sort order within each partition. Unlike a GSI, it can be read with strong consistency.

The catches: an LSI must be created when the table is created and can't be added later, and it shares the partition's throughput and the 10 GB per-partition-key size limit. Most designs reach for a GSI instead.

GSILSI
Partition keyAny attributeSame as base table
ConsistencyEventual onlyStrong or eventual
When createdAny timeOnly at table creation
CapacityIts ownShared with base table

Q17. What do BatchGetItem and BatchWriteItem do?

BatchGetItem reads up to 100 items across one or more tables in a single call. BatchWriteItem puts or deletes up to 25 items per call. Both cut round trips, which lowers latency when you're moving many items.

They aren't transactions: individual items can fail and come back as unprocessed, so you retry those. If you need all-or-nothing, use the transaction APIs instead.

python
with table.batch_writer() as batch:
    for user in users:          # boto3 handles 25-item chunks
        batch.put_item(Item=user)

Q18. Why do you sometimes need expression attribute names?

Many attribute names collide with DynamoDB reserved words (name, status, size, count, and hundreds more). Using one directly in an expression throws an error. Expression attribute names, the placeholders starting with #, let you reference them safely.

The habit worth forming: use #name placeholders for attributes and :val placeholders for values in every expression, so reserved words and injection are never a problem.

python
table.update_item(
    Key={"userId": "u#42"},
    UpdateExpression="SET #s = :new",
    ExpressionAttributeNames={"#s": "status"},   # status is reserved
    ExpressionAttributeValues={":new": "active"},
)

Q19. What is the maximum item size, and how do you store larger data?

A single item can be at most 400 KB, counting every attribute name and value, including nested lists and maps. That limit is hard, so a design that grows an item without bound eventually fails a write, which is why blobs don't belong inside the item.

For anything bigger, store the blob in S3 and keep only the S3 key plus metadata in the DynamoDB item. This keeps items small, reads cheap, and sidesteps the limit entirely.

Q20. What is Time to Live (TTL) in DynamoDB?

TTL lets you mark an attribute holding a Unix timestamp as an expiry field. DynamoDB deletes items automatically after that time, at no extra cost, without consuming write capacity for the deletion.

It's the right tool for sessions, temporary tokens, and event data with a natural lifespan. Deletion isn't instant; items expire within a window after their timestamp, so don't rely on it for exact-second cleanup.

python
import time
# expire this session 24 hours from now
table.put_item(Item={
    "sessionId": "s#abc",
    "expiresAt": int(time.time()) + 86400,   # TTL attribute
})
Back to question list

DynamoDB Intermediate Interview Questions

Intermediate20 questions

For candidates with working experience: data modeling, index judgment, and the questions that separate users from understanders.

Q21. What is single-table design and why do people use it?

Single-table design stores multiple entity types (users, orders, products) in one table, using key prefixes and overloaded keys to keep related items together and serve many access patterns from one table.

The reason is performance and cost: one Query can fetch a user and all their orders in a single request if they share a partition key, instead of joining across tables. The cost is complexity; the design is harder to read and change later.

text
PK           SK              attributes
USER#42      PROFILE#42      name, email
USER#42      ORDER#2026-001  total, status
USER#42      ORDER#2026-002  total, status

// One Query on PK = USER#42 returns the profile and all orders

Key point: The honest senior take is that single-table design is a trade-off, not a default. Saying 'I'd well-modeled separate tables and consolidate when access patterns demand it' indicates experience comes first.

Watch a deeper explanation

Video: AWS re:Invent 2021: DynamoDB deep dive: Advanced design patterns (AWS Events, YouTube)

Q22. Why is DynamoDB modeling described as access-pattern driven?

In a relational database you model the data, then write queries. In DynamoDB you list the queries first, then design keys and indexes so each query is a single efficient lookup. The schema serves the access patterns, not the other way around.

This is why the first modeling question in an interview is usually 'what are your access patterns?'. If you design keys before listing reads and writes, you end up needing Scans, which defeats the point of the database.

The DynamoDB data-modeling sequence

1List access patterns
every read and write the app needs, by name
2Identify entities and relationships
users, orders, and how they connect
3Design keys
partition and sort keys that serve those patterns
4Add indexes for the rest
GSIs for patterns the primary key can't serve

Interviewers watch for this order. Designing keys before listing patterns is the classic beginner mistake.

Q23. What is a hot partition and how do you avoid it?

A hot partition happens when one partition key value gets far more traffic than others, so requests concentrate on a single partition and throttle even though the table has spare capacity overall.

You avoid it by choosing a high-cardinality partition key that spreads traffic evenly, and by adding a random or calculated suffix (write sharding) when one logical key is unavoidably hot, like a viral item's counter.

python
import random
# Write sharding: spread a hot counter across 10 partitions
shard = random.randint(0, 9)
pk = f"VIDEO#viral123#{shard}"
# reads sum across all 10 shards

Key point: Adaptive capacity now absorbs mild hotspots automatically, so mention it, then say it doesn't rescue a fundamentally skewed key. That nuance is the mark of someone who's operated a table.

Q24. When do you choose a GSI over an LSI?

Choose a GSI in almost every case: it can use any attribute as its key, can be added after the table exists, and has independent capacity. Choose an LSI only when you need strong consistency on the alternate sort order and you know the requirement at table-creation time.

The LSI constraints are real deal-breakers: it must exist from creation, shares the base partition's throughput, and forces the partition's items under a 10 GB limit. That's why most teams standardize on GSIs.

Q25. What are GSI projection types and why do they matter?

A GSI projects a copy of chosen attributes. KEYS_ONLY projects just the keys, INCLUDE projects the keys plus named attributes, and ALL projects every attribute. More projection means a bigger, more expensive index but reads that don't fetch back from the base table.

The judgment call: project exactly what the index's queries return. Under-project and every read pays a second lookup against the base table; over-project and you pay storage and write cost for attributes nobody queries there.

ProjectionWhat's storedTrade-off
KEYS_ONLYIndex and table keys onlySmallest, but reads fetch back for other attributes
INCLUDEKeys plus named attributesBalanced; project what queries need
ALLEvery attributeNo fetch-back, but largest and priciest

Q26. What are conditional writes and what do they prevent?

A conditional write only succeeds if a condition expression is true, checked atomically on the item. It's how you prevent overwriting newer data, enforce uniqueness, or implement optimistic locking without a read-then-write race.

The classic uses: attribute_not_exists(pk) to create an item only if it's new, and a version check to make sure nobody changed the item since you read it.

python
from botocore.exceptions import ClientError
try:
    table.put_item(
        Item={"userId": "u#42", "email": "asha@example.com"},
        ConditionExpression="attribute_not_exists(userId)",  # create only if new
    )
except ClientError as e:
    if e.response["Error"]["Code"] == "ConditionalCheckFailedException":
        handle_duplicate()

Key point: Naming optimistic locking with a version attribute is the follow-up interviewers hope for when they ask about concurrency without a lock.

Q27. How do DynamoDB transactions work?

TransactWriteItems and TransactGetItems group up to 100 actions across one or more tables into an all-or-nothing operation with ACID guarantees. If any condition fails or any item conflicts, the whole transaction rolls back.

Transactions cost twice the capacity of the equivalent single operations, because DynamoDB does a prepare and a commit phase. Use them for genuine multi-item invariants, like transferring a balance, not for routine writes.

python
client.transact_write_items(TransactItems=[
    {"Update": {"TableName": "accounts", "Key": {"id": {"S": "A"}},
                "UpdateExpression": "SET bal = bal - :amt",
                "ConditionExpression": "bal >= :amt",
                "ExpressionAttributeValues": {":amt": {"N": "100"}}}},
    {"Update": {"TableName": "accounts", "Key": {"id": {"S": "B"}},
                "UpdateExpression": "SET bal = bal + :amt",
                "ExpressionAttributeValues": {":amt": {"N": "100"}}}},
])

Q28. What are DynamoDB Streams and what are they used for?

DynamoDB Streams captures an ordered log of every item-level change (insert, update, delete) and keeps it for 24 hours. You configure what the record contains: keys only, the new image, the old image, or both.

The common pattern is a Lambda triggered per change for replication, search indexing, notifications, aggregations, or maintaining a materialized view. It's how you react to writes without polling the table.

python
def handler(event, context):
    for record in event["Records"]:
        if record["eventName"] == "INSERT":
            new = record["dynamodb"]["NewImage"]
            index_in_search(new)   # e.g. push to OpenSearch

Q29. What is DynamoDB Accelerator (DAX)?

DAX is an in-memory cache built for DynamoDB that cuts read latency from single-digit milliseconds to microseconds for cache hits. It's API-compatible, so app code barely changes, and it handles read-through caching for you.

It fits read-heavy workloads with repeated reads of the same items. It doesn't help write-heavy patterns, and because it's a cache, reads through it are eventually consistent; strongly consistent reads bypass DAX and hit the table.

Key point: Saying 'DAX caches are eventually consistent, so I wouldn't use it where a read must reflect the latest write' shows you know its boundary, not just its pitch.

Q31. What is adaptive capacity?

Adaptive capacity lets DynamoDB shift unused throughput toward partitions that need it and isolate a hot partition key onto its own partition. It smooths out uneven access automatically, so mild skew no longer causes throttling the way it once did.

It's automatic and free, but it's not a cure for a badly chosen partition key. Sustained heavy skew on one value still needs a better key or write sharding; adaptive capacity buys headroom, not immunity.

Q32. What is an overloaded GSI (GSI overloading)?

GSI overloading reuses one generic index across many entity types by storing different meanings in the same index key attributes per item. A single GSI can then serve several access patterns instead of creating one index per pattern.

It keeps you under the index limit and cost down, at the price of readability. The keys hold values like TYPE#STATUS that only make sense with the design in front of you, so document it well.

Q33. What is a sparse index and when is it useful?

A sparse index only contains items that actually have the index's key attribute set. Items missing that attribute never make it into the index at all, so the index stays small, cheap, and fast to query even when the base table holds millions of items you don't care about.

It's the efficient way to query a subset. Set the GSI key only on items you want to find, like adding an attribute openTickets only to unresolved tickets, and the index becomes a ready-made filtered view.

python
# Only unresolved tickets set the GSI sort key, so the
# open-tickets GSI stays tiny and lists exactly them.
table.update_item(
    Key={"ticketId": "t#9"},
    UpdateExpression="SET gsiStatus = :open",
    ExpressionAttributeValues={":open": "OPEN"},
)
# On resolve, REMOVE gsiStatus so the item leaves the index.

Q34. How do you calculate capacity for a workload?

Start from item size and request rate. For writes, divide item size by 1 KB (round up) and multiply by writes per second to get WCUs. For reads, divide by 4 KB (round up) for strongly consistent, then halve for eventually consistent, multiplied by reads per second.

Then add headroom for spikes and remember transactions and GSIs consume their own capacity. Getting the rounding and the read-vs-write divisors right is the whole point of the question.

text
Write: 8 KB item, 50 writes/sec
  ceil(8 / 1) * 50 = 400 WCU

Read: 8 KB item, 100 reads/sec, eventually consistent
  ceil(8 / 4) * 100 / 2 = 100 RCU

Q35. How should an application handle DynamoDB errors?

Separate retryable from non-retryable. Throttling and internal server errors are retryable with exponential backoff and jitter, which the AWS SDKs do by default. Validation errors, conditional check failures, and access-denied are not; retrying just repeats the failure.

For batch operations, always process the UnprocessedItems or UnprocessedKeys the response returns, re-sending only those with backoff. Ignoring them silently drops data.

Q36. What backup and recovery options does DynamoDB offer?

On-demand backups take a full snapshot you keep as long as you want. Point-in-time recovery (PITR) continuously backs up the table so you can restore to any second in the last 35 days, which protects against accidental writes and deletes.

Both restore into a new table rather than overwriting the original, so you validate before switching over. PITR is the one to enable on anything important; the continuous coverage is worth the small cost.

Q37. What are DynamoDB global tables?

Global tables replicate one table across multiple AWS regions with active-active writes, so users in every region read and write against their nearest copy with low latency, and each change propagates out to the other regions automatically without you running any replication yourself.

Replication is asynchronous and eventually consistent across regions. Concurrent writes to the same item in different regions are resolved last-writer-wins by timestamp, so design so a given item is usually written in one region to avoid surprises.

Key point: The last-writer-wins conflict rule is the follow-up. Knowing it, and steering writes for one item to one region, is what The production-ready answer includes.

Q38. Why doesn't a FilterExpression save read capacity?

A FilterExpression runs after DynamoDB reads the items, so you're charged for every item Query or Scan reads, not the smaller set the filter returns. It reduces network payload, not cost.

The lesson is to filter with keys, not with FilterExpression. Put the filtering attribute into the sort key or a GSI so the read only touches matching items in the first place.

Q39. How many indexes can a table have, and why does it matter?

A table can have up to 20 global secondary indexes and up to 5 local secondary indexes by default. Once you hit that ceiling you either overload a single index to serve several access patterns or rethink the model, because you can't just keep adding one index per query forever.

Each GSI also costs write capacity, because every base-table write that touches a projected attribute writes to the index too. So indexes aren't free; more of them means higher write cost and more moving parts, which is why overloading exists.

Q40. How do you develop and test against DynamoDB locally?

DynamoDB Local is a downloadable version that runs on your machine or in a container, speaking the same API. You point the SDK at the local endpoint, so tests run fast and offline with no AWS charges.

It's close enough for functional tests of your queries and writes. It doesn't model real capacity, throttling, or multi-region behavior, so load and consistency edge cases still need a real table.

python
import boto3
# Point boto3 at DynamoDB Local for tests
dynamodb = boto3.resource(
    "dynamodb",
    endpoint_url="http://localhost:8000",
    region_name="us-east-1",
)
Back to question list

DynamoDB Interview Questions for Experienced Engineers

Experienced20 questions

advanced rounds probe internals, design judgment, and production scars. Expect every answer here to draw a follow-up.

Q41. How does DynamoDB partition data internally?

DynamoDB hashes each item's partition key to place it on one of many physical partitions, each holding up to 10 GB and a fixed throughput ceiling (roughly 3,000 RCUs and 1,000 WCUs). As data or throughput grows past a partition's limits, DynamoDB splits it and redistributes items automatically.

This is why partition key cardinality drives performance: traffic is only as balanced as the keys are distributed. A partition split is transparent, but the per-partition ceilings explain why one hot key throttles even on a large, well-provisioned table.

Key point: The per-partition limits (10 GB, ~3,000 RCU, ~1,000 WCU) are the numbers that make hot-partition math concrete. Reaching for them separates readers from operators.

Watch a deeper explanation

Video: AWS re:Invent 2019: Amazon DynamoDB deep dive: Advanced design patterns (DAT403-R1) (AWS Events, YouTube)

Q42. How do you model a many-to-many relationship in DynamoDB?

Use the adjacency list pattern: store each relationship as its own item, and use a GSI to traverse it in both directions. A user-in-groups example stores a membership item per pair, keyed so you can query all groups for a user and, via the GSI, all users in a group.

There are no join tables that get joined at read time. You precompute the relationship as items and read each direction as a single Query, which is the whole trick of relational modeling in a key-value store.

text
PK          SK          (GSI: PK=SK, SK=PK)
USER#1      GROUP#A     -> query GROUP#A to list its users
USER#1      GROUP#B
USER#2      GROUP#A

// Query PK=USER#1  -> groups for user 1
// Query GSI PK=GROUP#A -> users in group A

Q43. How does DynamoDB achieve durability and its consistency guarantees?

Every write is synchronously replicated to multiple storage nodes across three Availability Zones before it's acknowledged, which is what makes writes durable. A write succeeds once a quorum of replicas has it.

A strongly consistent read is routed to the leader replica that has every acknowledged write; an eventually consistent read may hit a follower that's milliseconds behind. That leader-vs-follower routing is the mechanism behind the consistency choice you make per read.

Q44. How do you optimize DynamoDB cost on a large table?

Attack the biggest levers: switch spiky tables to on-demand and steady ones to provisioned with auto scaling, shrink items (short attribute names, move blobs to S3), and prune GSIs and their projections since each write fans out to them.

Then reduce work: replace Scans with Queries or GSIs, use eventually consistent reads where staleness is fine to halve read cost, cache hot reads with DAX, and set TTL to expire data instead of paying to store and scan it. Measure with CloudWatch and Cost Explorer before and after.

Key point: Leading with 'measure first, then attack the biggest line item' frames this as engineering, not guessing, which is exactly what the question screens for.

Q45. A single item is getting hammered and throttling. Walk through your options.

First confirm it with CloudWatch Contributor Insights to see which key is hot. Then, in order of effort: rely on adaptive capacity for mild cases, put a cache (DAX or an application cache) in front of read-heavy hot items, and write-shard the key by appending a suffix so writes spread across partitions, reading by summing the shards.

For a monotonically increasing counter, the shard-and-sum pattern is the standard fix. The judgment is matching the tool to whether the heat is reads (cache) or writes (sharding).

Diagnosing and fixing a hot key

1Confirm the hot key
CloudWatch Contributor Insights shows the skewed key
2Classify the heat
is it read-heavy or write-heavy?
3Reads: add a cache
DAX or app cache absorbs repeated reads
4Writes: shard the key
suffix spreads writes; reads sum the shards

Reach for the cheapest fix that matches the traffic shape. Sharding adds read complexity, so don't apply it to a read-only hotspot.

Q46. How do you build reliable processing on DynamoDB Streams?

Streams give ordered, at-least-once delivery per shard, so your consumer must be idempotent: the same change record can arrive twice, and processing it twice must be safe. Key your downstream writes on the item's identity plus a version or sequence number so replays are no-ops.

Also handle failure without blocking the shard: a poison record that keeps failing stalls everything behind it in that shard, so use a retry limit and a dead-letter queue. Order is only guaranteed within a shard, not across the whole table.

Key point: Saying 'at-least-once, so I make the consumer idempotent' is the answer. Claiming exactly-once delivery is the wrong answer the key signal is.

Q47. How would you migrate a relational table to DynamoDB?

Start from access patterns, not the existing schema. Catalog every query the relational app runs, then design DynamoDB keys and GSIs to serve them, denormalizing where a join used to be. The relational schema is a starting inventory, not a template.

For the move itself: dual-write or backfill with a controlled job, verify with shadow reads comparing both stores, then cut over. Use DynamoDB Streams to keep derived data in sync during the transition. The hard part is the modeling shift, not the data transfer.

Q48. Explain write sharding and its read-side cost.

Write sharding appends a suffix (random 0..N or a hash) to a partition key that would otherwise be hot, spreading writes across N partitions. A viral post's like counter, for example, becomes N counter items instead of one contended item.

The cost lands on reads: to get the true value you must read all N shards and combine them, turning one GetItem into N reads plus aggregation. So you shard only as wide as the write pressure needs, because every extra shard is another read every time.

python
N = 10
# write: pick a random shard
shard = random.randint(0, N - 1)
table.update_item(
    Key={"pk": f"POST#{post_id}#{shard}"},
    UpdateExpression="ADD likes :one",
    ExpressionAttributeValues={":one": 1},
)
# read: sum across all N shards
total = sum(read_shard(post_id, s) for s in range(N))

Q49. Can a GSI throttle the base table, and how?

Yes. In provisioned mode, if a GSI runs out of write capacity, back-pressure propagates and base-table writes that update the index start throttling too, because DynamoDB won't let the index fall arbitrarily behind.

The fixes: provision GSI capacity to match the base table's write rate on projected attributes, or use on-demand so both scale together. Projecting fewer attributes also helps, since a write only touches the index if it changes a projected attribute.

Q50. How do you handle items that approach or exceed 400 KB?

Split the data. Move large blobs (documents, images, big JSON) to S3 and store only the S3 key and metadata in DynamoDB. For large structured records, break them into multiple items under one partition key so a Query reassembles them, keeping each item small.

Vertical partitioning also helps: put rarely read big attributes in a separate item so the hot path reads a small item. The goal is small items on the read path, because item size drives both RCU cost and latency.

Q51. How do you implement optimistic locking in DynamoDB?

Keep a version attribute on the item. On update, condition the write on the version matching what you read, and increment it in the same call. If another writer got in first, the version won't match and the conditional write fails, so you re-read and retry.

This gives safe concurrent updates without a lock service. It's the right tool when conflicts are rare; under heavy contention on one item, the retries pile up and you're back to a hot-key problem.

python
table.update_item(
    Key={"id": "cart#7"},
    UpdateExpression="SET #items = :new, version = version + :one",
    ConditionExpression="version = :expected",
    ExpressionAttributeNames={"#items": "items"},
    ExpressionAttributeValues={
        ":new": new_items, ":expected": read_version, ":one": 1,
    },
)  # fails with ConditionalCheckFailedException if someone else wrote first

Q52. How do you model time-series data in DynamoDB?

Partition by a time bucket plus an entity so writes spread over time instead of hammering one key. A common shape is partition key like DEVICE#123#2026-07 and a sort key of the exact timestamp, so a month's readings live together and range queries by time are cheap.

Pair it with TTL to expire old data automatically, and consider rolling old buckets to cheaper storage. The anti-pattern is a single partition key for all events, which turns the newest bucket into a permanent hot partition.

text
PK                    SK (timestamp)        value
DEVICE#123#2026-07    2026-07-04T10:00:00Z  22.4
DEVICE#123#2026-07    2026-07-04T10:05:00Z  22.6

// Query PK + SK between two timestamps for a time range
// TTL attribute drops readings older than the retention window

Q53. How do you design an app around eventual consistency?

Assume a read right after a write might not see it, especially on GSIs, which are always eventually consistent. Design flows so the user isn't blocked on immediate read-after-write: return the value you just wrote from memory instead of re-reading, or use a strongly consistent read on the base table for that one path.

For derived data built from Streams, embrace the lag and make consumers idempotent. The failure mode is UI that reads a GSI immediately after a write and shows stale data; route that specific read to the base table with strong consistency.

Q54. How does DynamoDB compare to Cassandra, and when would you pick each?

Both are partitioned, high-throughput NoSQL stores with similar data models, and DynamoDB's design descends from the original Dynamo paper. The real difference is operations: DynamoDB is fully managed and serverless, while Cassandra is a cluster you run, tune, and scale yourself.

Pick DynamoDB when you want zero operational overhead and are in AWS. Pick Cassandra when you need multi-cloud or on-prem control, want to avoid vendor lock-in, or have the team to operate a cluster and want to tune replication and consistency yourself.

DynamoDBCassandra
OperationsFully managedSelf-managed cluster
HostingAWS onlyAnywhere
ScalingAutomaticAdd and rebalance nodes
Consistency tuningPer-read choiceTunable per query (quorum levels)

Q55. What DynamoDB metrics do you monitor in production?

Watch ThrottledRequests and the throttle events split by read and write to catch capacity or hot-key trouble early, consumed vs provisioned capacity to size correctly, and SuccessfulRequestLatency to spot degradation. Contributor Insights surfaces the most-accessed keys, which is how you find a hot partition before users do.

For GSIs, monitor their consumed capacity separately, since a starved index can throttle base writes. Alarm on sustained throttling rather than single spikes, because the SDK's backoff absorbs brief ones.

Q56. Design question: use DynamoDB for a URL shortener at scale.

List access patterns first: create a short code, resolve a short code to its long URL, and maybe list a user's links. Then the table is simple: partition key is the short code, attributes are the long URL, owner, and created time. Resolution is a single GetItem, which is exactly the cheap lookup DynamoDB is built for.

For code generation, avoid a global counter (a hot key); generate a random code and use a conditional PutItem with attribute_not_exists to guarantee uniqueness, retrying on the rare collision. Add a GSI on owner for the list-my-links pattern, cache hot codes with DAX or a CDN, and use on-demand capacity to ride traffic spikes.

python
import secrets
def create_short(long_url, owner):
    while True:
        code = secrets.token_urlsafe(6)
        try:
            table.put_item(
                Item={"code": code, "url": long_url, "owner": owner},
                ConditionExpression="attribute_not_exists(code)",
            )
            return code
        except ClientError as e:
            if e.response["Error"]["Code"] != "ConditionalCheckFailedException":
                raise   # real error; only retry on collision

Key point: Structuring the answer as patterns, keys, code generation, then scaling knobs is what the question scores. Jumping straight to a schema without listing access patterns is the miss.

Watch a deeper explanation

Video: DynamoDB Deep Dive with an Ex-Meta Staff Engineer (Hello Interview, YouTube)

Q57. You inherited a table that relies on Scans. How do you fix it?

Find every Scan and the query it's really trying to answer, then serve that query with keys or a GSI instead. If code scans and filters by status, add a GSI keyed on status (or a sparse index for the subset) so the same result is a Query that reads only matching items.

Roll it out safely: add the index, backfill it, switch reads over, verify results match, then delete the Scan path. Where a full-table read is genuinely needed (a nightly export), use a parallel Scan with segments, but treat that as the exception.

Q58. How do you design a multi-tenant application on DynamoDB?

Prefix the partition key with a tenant ID (TENANT#42#...) so each tenant's data is naturally isolated and every query is scoped to one tenant. Enforce it with IAM condition keys that restrict a caller to items whose partition key begins with their tenant, so isolation holds even if app code has a bug.

Watch for a large tenant becoming a hot partition; shard their keys if needed. For strict isolation or wildly different sizes, a table per tenant is an option, at the cost of more tables to manage. The pooled single-table model is the common default.

Q59. What operational limits and gotchas surprise teams in production?

The ones that bite: you can switch between capacity modes only once every 24 hours, a partition holds at most 10 GB per partition key value under an LSI, item size caps at 400 KB, and Streams retain records for just 24 hours so a stalled consumer loses data.

Also, transactions and strongly consistent reads cost more capacity than their basic equivalents, and adding an LSI is impossible after table creation. Knowing these before they surprise you in an incident is what production experience buys.

Q60. When would you argue against using DynamoDB?

When access patterns are unknown or keep changing, DynamoDB's up-front modeling works against you; a relational database's ad-hoc queries fit better. It's also wrong for heavy analytics, reporting with joins and aggregations, and full-text search, which belong in a warehouse or a search engine.

The production signal is refusing to treat it as a default. DynamoDB shines for known, high-scale, low-latency patterns; recommending Postgres or OpenSearch when those fit better is the answer that shows judgment rather than allegiance.

Key point: Interviewers plant this to see if you're a one-tool engineer. Naming concrete cases where you'd pick something else is the whole point.

Back to question list

Why DynamoDB? DynamoDB vs relational and other NoSQL stores

DynamoDB wins when you need predictable low latency at scale with almost no operational work, and when your access patterns are known up front. It trades away flexible ad-hoc querying and joins for guaranteed performance and automatic scaling. Where it loses is analytics, complex reporting, and workloads whose query shapes keep changing, which fit a relational database or a search engine better. Saying these trade-offs out loud is itself an interview signal: it shows you pick a data store on its merits, not by habit.

StoreData modelBest atWatch out for
DynamoDBKey-value and documentPredictable low-latency reads and writes at scaleAd-hoc queries, joins, analytics
PostgreSQL / MySQLRelationalJoins, transactions, flexible queryingManual scaling, sharding under heavy load
MongoDBDocumentRich document queries, flexible schemaOps and tuning at scale you manage yourself
CassandraWide-columnWrite-heavy, multi-region, self-hostedYou run the cluster; steeper operations
RedisIn-memory key-valueCaching, sub-millisecond readsDurability and dataset size limited by memory

How to Prepare for a DynamoDB Interview

Prepare in layers, and practice out loud. Most DynamoDB rounds move from concept questions to a data-modeling exercise to a debugging or design discussion, so rehearse each stage rather than only reading answers.

  • Master your tier's concepts until you can explain them without notes, then read one tier up for the stretch questions.
  • Model a real app on paper: list access patterns first, then design keys and indexes to serve each one.
  • Practice thinking aloud with a timer, because your reasoning about trade-offs, not just the final schema is the technical point.
  • Take the quiz on this page to find weak spots, then revisit those questions before the real round.

The typical DynamoDB interview flow

1Recruiter or phone screen
background, motivation, a few NoSQL concept checks
2Core concepts
partition and sort keys, indexes, capacity, consistency
3Data modeling exercise
design keys and access patterns for a sample app
4Design or debugging
hot partitions, throttling, cost trade-offs, follow-ups

Earlier rounds increasingly run as AI coding interviews. The concepts on this page are what gets probed at every stage.

Test Yourself: DynamoDB Quiz

Ready to test your DynamoDB knowledge?

10 questions, about 6 minutes. Score 70% or higher to earn a shareable certificate.

10 questions Instant feedback Free certificate on 70%+

Frequently  Asked  Questions

Which DynamoDB topics should I prioritize before a technical round?

Prioritize the areas that change real decisions: fundamentals, practical tasks, debugging, trade-offs, and evidence. The highest-value questions are tied to a project example, a validation check, or a failure mode.

Are these questions enough to pass a DynamoDB interview?

They cover the question-answer portion well, but most DynamoDB rounds also include a data-modeling exercise: designing keys and access patterns for a sample app while explaining your reasoning. modeling a real app out loud with a timer is the practice path. Our AI coding interview prep guide covers that format, including how automated evaluation reads your process.

Do I need AWS experience to answer these?

It helps, but the concepts matter more than console clicks. Interviewers care whether you understand partition keys, indexes, capacity modes, and consistency, not whether you've memorized every SDK method. If you've used any key-value store, most of these ideas transfer, and the code here uses the plain AWS SDK so you can see the shape.

How long does it take to prepare for a DynamoDB interview?

If you use DynamoDB at work, one to two weeks of an hour a day covers this bank with modeling practice. Starting colder, plan three to four weeks and model a real app daily; reading answers without designing a table is how preparation quietly fails.

Do interviewers ask exactly these questions?

The concepts repeat far more reliably than the exact wording. Interviewers rephrase, chain follow-ups, and push toward whatever you claim confidence in. Prepare the underlying ideas, partition keys, indexes, consistency, single-table design, and the phrasing takes care of itself.

Is there a way to test my DynamoDB knowledge?

Yes. The quiz on this page scores you as you go and explains every answer, so you find your weak spots fast. Pass the threshold and you can download a shareable certificate with your name and score, free and with no sign-up. It's the quickest way to check yourself before the real round.

From the team that builds coding interviews

Hyring builds the AI Coding Interviewer that runs live technical rounds in 20+ languages for 5,000+ hiring teams. These DynamoDB questions and scoring notes reflect what actually gets asked and evaluated inside the interviews we host.

See how the AI Coding Interviewer works

Sources

Adithyan RKWritten by Adithyan RK
Surya N
Fact-checked by Surya N
Published on: 28 May 2026Last updated: 19 Jul 2026
Share: