Configure DynamoDB TTL for Automatic Item Expiration and Cost Reduction
Enable DynamoDB TTL to automatically expire items using an epoch-second attribute. Deletions run asynchronously within 48 hours, consume no write capacity, and emit stream records for audit. Verify with CloudWatch metric TimeToLiveDeletedItemCount and filter reads for immediate consistency.
11 Nov 2026, 15:12 UTC

Desired Outcome
Enable Time to Live (TTL) on a DynamoDB table so that items automatically expire after a specified timestamp, reducing storage costs and eliminating manual cleanup logic. Expired items are deleted asynchronously within 48 hours without consuming write capacity units.
Prerequisites
- An existing DynamoDB table or permission to create one (
dynamodb:CreateTable,dynamodb:UpdateTimeToLive). - A designated attribute of type Number (epoch seconds) in your item schema to hold the expiration timestamp. The attribute name must be consistent across items but can be sparse (items without it never expire).
- AWS CLI v2 configured with appropriate credentials, or access to the AWS Console / CloudFormation.
- Optional: DynamoDB Streams enabled on the table if you need audit trails or downstream processing of TTL deletions.
Procedure
1. Choose or Add the TTL Attribute
Decide on an attribute name (e.g., expiresAt or ttl). Ensure your application writes a Unix epoch timestamp (seconds since 1970-01-01 UTC) as a Number type when creating or updating items.
// Example item with TTL attribute (expires 24 hours from now)
{
"pk": "user#123",
"sk": "session#abc",
"data": "{...}",
"expiresAt": 1731379200 // Number, epoch seconds
}If the attribute is missing from an item, that item will never expire. Plan default TTL values in your application code for new items.
2. Enable TTL on the Table
Via AWS CLI:
aws dynamodb update-time-to-live \
--table-name YourTableName \
--time-to-live-specification Enabled=true,AttributeName=expiresAtVia AWS Console: Navigate to the table → Time to Live tab → Enable → enter the attribute name → Save.
Via CloudFormation:
Resources:
MyTable:
Type: AWS::DynamoDB::Table
Properties:
TableName: YourTableName
AttributeDefinitions:
- AttributeName: pk
AttributeType: S
KeySchema:
- AttributeName: pk
KeyType: HASH
TimeToLiveSpecification:
AttributeName: expiresAt
Enabled: true3. Verify TTL Status
Confirm TTL is active and the attribute name is correct:
aws dynamodb describe-time-to-live --table-name YourTableNameExpected output shows TimeToLiveStatus: ENABLED and AttributeName: expiresAt.
Expected Checks
Monitor Background Deletions
DynamoDB exposes the CloudWatch metric TimeToLiveDeletedItemCount (namespace AWS/DynamoDB, dimensions TableName). Create an alarm or dashboard to track deletion volume.
aws cloudwatch get-metric-statistics \
--namespace AWS/DynamoDB \
--metric-name TimeToLiveDeletedItemCount \
--dimensions Name=TableName,Value=YourTableName \
--start-time 2026-11-10T00:00:00Z \
--end-time 2026-11-11T00:00:00Z \
--period 3600 \
--statistics SumValidate Stream Records (If Streams Enabled)
Each TTL deletion emits a stream record with userIdentity.type set to TTL. Inspect records to confirm deletions are flowing:
aws dynamodb get-shard-iterator \
--table-name YourTableName \
--shard-id shardId-000000000000 \
--shard-iterator-type LATEST
# Then use get-records and filter for userIdentity.type == "TTL"Test with Known Expired Items
Insert test items with timestamps in the past (e.g., expiresAt: 1) and scan the table after 48 hours to confirm removal. Use DescribeTimeToLive to verify the table still reports ENABLED.
Operational Considerations
Read Consistency and Filtering
Expired items remain readable until the background process deletes them (up to 48 hours past the timestamp). If your application requires immediate exclusion, add a filter expression to reads:
// Pseudocode for conditional read
query(
KeyConditionExpression: "pk = :pk",
FilterExpression: "expiresAt > :now",
ExpressionAttributeValues: { ":pk": "user#123", ":now": currentEpochSeconds }
)Point-in-Time Recovery (PITR)
PITR backups include expired items until they are physically removed. Restoring a backup will re-evaluate TTL against the current time, so restored items may expire immediately if their timestamp is in the past.
Capacity Impact
High-volume TTL deletions can temporarily increase read latency during background cleanup. Monitor ConsumedReadCapacityUnits and ReadThrottleEvents if you enable TTL on a large table with many expired items.
Recovery Options
TTL deletions are not transactional and cannot be rolled back. Once an item is deleted by TTL, it is gone unless you have a PITR backup or an external copy. Before enabling TTL on a production table:
- Test on a staging table with representative data and expiration patterns.
- Verify that your application can tolerate items persisting up to 48 hours past their expiration timestamp.
- Ensure downstream consumers (via Streams) can handle
userIdentity.type=TTLrecords correctly.
Limitations
- TTL precision is not real-time; deletions occur within 48 hours of the expiration timestamp.
- Sparse TTL attributes mean items without the attribute never expire — enforce defaults in application logic.
- TTL operates per table; there is no global or cross-table TTL mechanism.
- Deletions do not consume write capacity units but do generate stream records (if enabled) which count against stream read limits.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.