How DynamoDB TTL works
Time to Live (TTL) deletes items for you once they are no longer needed - sessions, tokens, caches, logs. You turn it on for a table and name one attribute; every item with that attribute expires at the moment it holds. The value has to be:
- a Number (
N) - a string with the same digits is ignored; - in Unix epoch seconds, the number of seconds since 1970-01-01 00:00:00 UTC - for example
1798761600for 2027-01-01 00:00 UTC; - no more than five years in the past - older values are ignored.
An item without the attribute, or with a value that breaks one of these rules, is simply never deleted. There is no error and no warning.
| What happens | Details |
|---|---|
| When the item is deleted | At any time after it expires, typically within a few days - not at the exact second. |
| Cost of the delete | None: TTL deletes consume no write capacity. In a global table, the deletes replicated to other Regions do consume replicated writes. |
| Secondary indexes | The item is removed from local and global secondary indexes, like any delete. |
| DynamoDB Streams | The delete appears as a service delete, with userIdentity.type "Service" and userIdentity.principalId "dynamodb.amazonaws.com". |
The milliseconds mistake: items that never expire
The most common TTL bug is a value in milliseconds. JavaScript's Date.now() and Java's System.currentTimeMillis() return milliseconds, so 1798761600000 ends up in the attribute. DynamoDB reads it as seconds - a date around the year 58,970 - and the item stays forever. The converter above flags such values: seconds have 10 digits today, milliseconds 13.
| Language | Current time in epoch seconds |
|---|---|
| JavaScript | Math.floor(Date.now() / 1000) |
| Python | int(time.time()) |
| Java | Instant.now().getEpochSecond() |
| Go | time.Now().Unix() |
| C# | DateTimeOffset.UtcNow.ToUnixTimeSeconds() |
| Shell | date +%s |
Add the lifetime in seconds: 90 * 24 * 60 * 60 for 90 days. Recompute it on every update if items should live 90 days from their last change rather than from their creation.
Expired items still show up in reads
Until the background process deletes an expired item, Query, Scan and GetItem return it, and it still counts towards storage and read costs. When expired data must not be used, filter it out by comparing the TTL attribute with the current time:
FilterExpression: #ttl > :now
ExpressionAttributeNames: {"#ttl": "expireAt"}
ExpressionAttributeValues: {":now": 1790000000} The same comparison as a ConditionExpression keeps a write from touching an expired item. Build either with the DynamoDB expression builder. Setting the attribute to a future time, or removing it, before the item is deleted keeps the item.
Turning TTL on
In the DynamoDB console: the table's Additional settings, Time to Live, Turn on, and the attribute name. With the AWS CLI:
aws dynamodb update-time-to-live --table-name YourTable \
--time-to-live-specification 'Enabled=true, AttributeName=expireAt'A table has one TTL attribute. It does not have to exist in any item yet, and items without it are never deleted by TTL.
Frequently asked questions
Why are my expired items not deleted?
Check, in this order: TTL is turned on for the table with the same attribute name; the value is a Number, not a string; it is in seconds, not milliseconds; it is less than five years in the past. If all of that holds, wait: deletion typically happens within a few days after the expiry.
Can the TTL attribute hold a date string such as 2027-01-01?
No. TTL takes only a Number in epoch seconds; an item whose TTL attribute is a string is never deleted. Convert the date above and store the number.
Does TTL delete items at the exact expiry time?
No. Expired items are deleted in the background, typically within a few days. If an application must not see them, filter by the TTL attribute in reads.
Is the timestamp sent anywhere?
No. The conversion runs in your browser: nothing you enter is uploaded, processed on a server or stored. The page only counts that the converter was used and what kind of value it got, never the value.
References
Using time to live (TTL) in DynamoDB
Computing time to live (TTL) in DynamoDB
Working with expired items and time to live (TTL)