Building DynamoDB TTL: Auto-Expire Old Data

 

Building DynamoDB TTL: Auto-Expire Old Data





Learn how to automatically delete stale data in DynamoDB using Time-to-Live (TTL).

In this lab, you’ll add an expiration attribute to items, enable TTL on the table, and watch DynamoDB clean up expired records automatically — all from your terminal.


Step 1: Create a Table with a TTL Attribute

In this step, you’ll create a table named SessionData with a partition key (SessionID).

You’ll also include a placeholder attribute ExpiresAt, which will later store an epoch timestamp.

aws dynamodb create-table \
  --table-name SessionData \
  --attribute-definitions AttributeName=SessionID,AttributeType=S \
  --key-schema AttributeName=SessionID,KeyType=HASH \
  --billing-mode PAY_PER_REQUEST

Output:

{
  "TableDescription": {
    "TableName": "SessionData",
    "TableStatus": "CREATING",
    "BillingModeSummary": { "BillingMode": "PAY_PER_REQUEST" },
    "ItemCount": 0
  }
}

Check table status until it’s active:

aws dynamodb describe-table --table-name SessionData --query "Table.TableStatus"

Output:

"ACTIVE"

Step 2: Insert Items with Expiration Timestamps

You’ll insert a few records with an ExpiresAt attribute that tells DynamoDB when to remove them.

TTL expects Unix epoch time (in seconds), not milliseconds.

Generate a timestamp that expires in ~5 minutes:

date -d "+5 minutes" +%s

Example Output:

1731465900

(Note: This date command works on Linux/macOS. For Windows PowerShell, use: [int][DateTimeOffset]::Now.AddMinutes(5).ToUnixTimeSeconds())

Insert two sessions:

aws dynamodb put-item \
  --table-name SessionData \
  --item '{"SessionID": {"S": "sess-1001"}, "User": {"S": "Alice"}, "ExpiresAt": {"N": "1731465900"}}'
aws dynamodb put-item \
  --table-name SessionData \
  --item '{"SessionID": {"S": "sess-1002"}, "User": {"S": "Bob"}, "ExpiresAt": {"N": "1731466200"}}'

Output:

{}

Confirm both are inserted:

aws dynamodb scan --table-name SessionData --projection-expression "SessionID, ExpiresAt"

Output:

{
  "Items": [
    {"SessionID": {"S": "sess-1001"}, "ExpiresAt": {"N": "1731465900"}},
    {"SessionID": {"S": "sess-1002"}, "ExpiresAt": {"N": "1731466200"}}
  ],
  "Count": 2
}

Step 3: Enable TTL on the Table

Enable DynamoDB TTL, specifying the ExpiresAt attribute:

aws dynamodb update-time-to-live \
  --table-name SessionData \
  --time-to-live-specification "Enabled=true, AttributeName=ExpiresAt"

Output:

{
  "TimeToLiveSpecification": {
    "AttributeName": "ExpiresAt",
    "Enabled": true
  }
}

Check TTL status:

aws dynamodb describe-time-to-live --table-name SessionData

Output:

{
  "TimeToLiveDescription": {
    "TimeToLiveStatus": "ENABLED",
    "AttributeName": "ExpiresAt"
  }
}

Step 4: Observe Item Expiration

DynamoDB’s TTL sweeper runs periodically (usually within minutes for small tables).

While waiting for it to remove expired items, you can continue querying the table to watch entries disappear in real time.

aws dynamodb scan --table-name SessionData --projection-expression "SessionID, ExpiresAt"

Example Output (after a few minutes):

{
  "Items": [
    {"SessionID": {"S": "sess-1002"}, "ExpiresAt": {"N": "1731466200"}}
  ],
  "Count": 1
}

Eventually, the table will be empty as all timestamps pass.

You’ll see expired records vanish automatically — no deletes required.


Step 5: Verify Cleanup via CloudWatch Metrics

While TTL cleanup is in progress, you can use CloudWatch metrics to confirm deletion activity.

aws cloudwatch get-metric-statistics \
  --namespace AWS/DynamoDB \
  --metric-name TimeToLiveDeletedItemCount \
  --start-time $(date -u -d "-15 minutes" +"%Y-%m-%dT%H:%M:%SZ") \
  --end-time $(date -u +"%Y-%m-%dT%H:%M:%SZ") \
  --period 300 \
  --statistics Sum \
  --dimensions Name=TableName,Value=SessionData

Output (example):

{
  "Datapoints": [
    {
      "Timestamp": "2025-10-20T21:45:00Z",
      "Sum": 2.0,
      "Unit": "Count"
    }
  ],
  "Label": "TimeToLiveDeletedItemCount"
}

This confirms DynamoDB’s background sweeper removed the expired items.


Step 6: Clean Up Resources

Delete your test table to close out the lab:

aws dynamodb delete-table --table-name SessionData

Confirm:

aws dynamodb list-tables

Output:

{"TableNames": []}

Wrap-Up

You’ve just implemented automatic data expiration in DynamoDB — no cron jobs, no Lambda functions, no manual deletes.

TTL is perfect for ephemeral data such as sessions, cache entries, or temporary tokens.

By combining TTL with Streams (from Vol. 2) you can even trigger downstream cleanup or analytics pipelines when items expire.


Pro Tip #1 — Use ISO 8601 + Epoch Together

For debugging, store both a human-readable timestamp and the numeric epoch:

"ExpiresAt": {"N": "1731466200"},
"ExpiresISO": {"S": "2025-10-20T21:30:00Z"}

You’ll instantly know what’s expiring when you scan the table.


Pro Tip #2 — Keep TTL Lightweight

TTL is best-effort, not instantaneous. Use it for non-critical cleanup, not precise scheduling.

If you need guaranteed expiry at a specific time, pair TTL with an EventBridge-triggered Lambda.


Aaron Rose is a software engineer and technology writer at tech-reader.blog and the author of Think Like a Genius.

Comments

Popular posts from this blog

The New ChatGPT Reason Feature: What It Is and Why You Should Use It

Raspberry Pi Connect vs. RealVNC: A Comprehensive Comparison

Insight: The Great Minimal OS Showdown—DietPi vs Raspberry Pi OS Lite