Development with AWS Services · Topic 6 of 7

DynamoDB Design and Data Lifecycles

Choose DynamoDB keys and indexes, use Query versus Scan and consistency models, and expire data with TTL, S3 Lifecycle rules and retention periods.

  • 5 min
In a nutshell
  • Pick a partition key with many distinct values and even access.
  • Query uses the key and is efficient; Scan reads everything, and filters apply after the read.
  • Reads are eventually consistent by default; ConsistentRead=True costs double and fails on a GSI.

What it is

Amazon DynamoDB stores items in tables and finds them by primary key. Fast, cheap access comes from choosing keys and indexes that match the questions your code asks.

Data also has a lifecycle. Old sessions, logs and messages should expire or move to cheaper storage on their own, instead of by hand. DynamoDB uses TTL, S3 uses Lifecycle rules, and other services use retention periods.

Applicationkey lookuppartition key hashPartitionstores itemssort key orderItem collectionordered by sort key

How it works

Keys and attributes

The primary key is either a partition key alone or a partition key plus a sort key. DynamoDB hashes the partition key to pick the physical partition, and keeps items with the same partition key sorted by the sort key.

  • Choose a high cardinality partition key, meaning one with many distinct values and evenly spread traffic, such as customerId. A key like status sends most traffic to one partition and causes throttling on a hot partition.
  • Other attributes are schema free, and one item can be up to 400 KB.
  • A composite key such as customerId plus orderDate lets one Query return a customer's orders in order.

Query, Scan and writes

OperationWhat it doesCost
GetItemReads one item by full keyCheapest
QueryNeeds the partition key, optionally a sort key conditionReads only that collection
ScanReads every item in the table or indexReads and pays for everything

A filter expression on a Scan or Query runs after the read, so it shrinks the response but not the capacity used. Each call returns at most 1 MB, and LastEvaluatedKey is your cue to call again with ExclusiveStartKey.

resp = table.query(
    KeyConditionExpression=Key("customerId").eq("c-17")
        & Key("orderDate").begins_with("2026-10"),
    ProjectionExpression="orderId, total",
)

For writes, PutItem replaces an item and UpdateItem changes attributes, including atomic counters. A ConditionExpression makes a write conditional, which supports optimistic locking with a version attribute. BatchGetItem, BatchWriteItem and transactions group operations.

Read consistency and capacity

Eventually consistentStrongly consistent
DefaultYesSet ConsistentRead=True
FreshnessMay lag a recent writeLatest committed data
CostOne RCU reads two items of 4 KBOne RCU reads one item of 4 KB
On a GSISupportedNot supported

One write capacity unit writes one item of up to 1 KB per second. In provisioned mode you set capacity, and in on demand mode DynamoDB scales for you. An exceeded limit returns ProvisionedThroughputExceededException, which the SDK retries with backoff.

Indexes

Local secondary indexGlobal secondary index
KeysSame partition key, different sort keyAny partition key and sort key
CreatedOnly at table creationAny time
ConsistencyEventual or strongEventual only
CapacityShares the table'sHas its own

Query an index by passing IndexName. Each index copies the attributes you project into it.

Expiring data with TTL

Enable TTL on a table and name an attribute that holds a Number of Unix epoch seconds. DynamoDB deletes expired items in the background, typically within a few days, and the deletes use no write capacity.

Expired items can still be returned until they are deleted, so filter them out in queries. TTL deletions appear in DynamoDB Streams.

S3 Lifecycle and retention periods

An S3 Lifecycle configuration is a set of rules, each with a filter by prefix, tag or size.

  • Transition actions move objects between storage classes, for example Standard to Glacier Flexible Retrieval after 30 days. Objects smaller than 128 KB do not transition by default.
  • Expiration actions delete current objects, noncurrent versions or expired delete markers, and can abort incomplete multipart uploads.
{"Rules":[{"ID":"logs","Status":"Enabled","Filter":{"Prefix":"logs/"},
 "Transitions":[{"Days":30,"StorageClass":"GLACIER"}],
 "Expiration":{"Days":365}}]}

Other services use retention periods. SQS keeps messages for 4 days by default, up to 14. Kinesis keeps records for 24 hours by default, up to 365 days. CloudWatch Logs keeps events forever unless you set a retention period on the log group.

How the exam asks about this

  • "Session items must disappear after 24 hours without any cleanup code." -> Enable TTL and store an expiry epoch in a Number attribute.
  • "Queries by email are needed on a table keyed by userId." -> Add a global secondary index on email.
  • "Logs in S3 are rarely read after 30 days and must be deleted after a year." -> A Lifecycle rule with a transition and an expiration.

What to remember for the exam

  • Pick a partition key with many distinct values and even access.
  • Query uses the key and is efficient; Scan reads everything, and filters apply after the read.
  • Reads are eventually consistent by default; ConsistentRead=True costs double and fails on a GSI.
  • A GSI can be added later, has its own capacity and is eventually consistent; an LSI exists only from table creation.
  • TTL needs a Number attribute in epoch seconds, deletes lazily and consumes no write capacity.
  • S3 Lifecycle rules transition and expire objects by prefix, tag or size.
  • Retention is set per service: SQS up to 14 days, Kinesis up to 365 days, log groups by policy.
Watch out

TTL is not exact. Do not rely on it for security or compliance deadlines, because expired items can remain readable for days.

Common mistakes

Using Scan for a routine lookup. A Scan with a filter still reads the whole table. Add a key or an index instead.

Storing the TTL as a string or in milliseconds. The attribute must be a Number in seconds, or the item is ignored.

Expecting strong reads from a GSI. Indexes replicate asynchronously. Use the base table for strongly consistent reads.

Check yourself

  • Why is status a poor partition key?

    It has few distinct values, so traffic concentrates on a few partitions and causes hot partition throttling.

  • When can you create a local secondary index?

    Only when the table is created; a global secondary index can be added later.

  • What type and unit must a TTL attribute use?

    A Number holding Unix epoch time in seconds.

Topic 6 of 7 in Development with AWS Services

Test yourself on Development with AWS Services

The full AWS DVA-C03 question bank has 850 questions, with timed practice exams and an explanation for every answer.

This study guide is independent and is not affiliated with, endorsed by, or sponsored by AWS. Vendor names, certification names and exam codes are trademarks of their respective owners and are used for identification only.