TTL (Time-To-Live)
Auto-delete items after a set time using DynamoDB's TTL feature.
What is TTL?
DynamoDB TTL lets you set an expiration time on items. When the time passes, DynamoDB automatically deletes the item. This is useful for:
- Session tokens
- Temporary data
- Cache entries
- Trial periods
- Audit logs with retention
TTL deletion is free - you don't pay for the delete operation. Items are usually deleted within 48 hours of expiration (often much faster).
Note
TTL must be enabled on your table. See AWS docs for setup.
Key features
TTLAttribute- stores datetime as epoch timestampExpiresInhelper - easy time calculationsis_expiredproperty - check if item expiredexpires_inproperty - get time remainingextend_ttl()method - extend expiration
Getting started
Basic usage
Add a TTLAttribute to your model:
from pydynox import Model, ModelConfig
from pydynox.attributes import ExpiresIn, StringAttribute, TTLAttribute
class Session(Model):
model_config = ModelConfig(table="sessions")
pk = StringAttribute(hash_key=True)
user_id = StringAttribute()
expires_at = TTLAttribute()
# Create session that expires in 1 hour
session = Session(
pk="SESSION#123",
user_id="USER#456",
expires_at=ExpiresIn.hours(1),
)
session.save()
# Check if expired
if session.is_expired:
print("Session expired")
# Get time remaining
remaining = session.expires_in
if remaining:
print(f"Expires in {remaining.total_seconds()} seconds")
# Extend by 1 hour
session.extend_ttl(ExpiresIn.hours(1))
ExpiresIn helper
Use ExpiresIn to calculate expiration times:
"""ExpiresIn helper methods."""
from pydynox.attributes import ExpiresIn
# All methods return a datetime in UTC
# Short-lived items
token_expires = ExpiresIn.minutes(15) # 15 minutes
session_expires = ExpiresIn.hours(1) # 1 hour
# Medium-lived items
cache_expires = ExpiresIn.hours(24) # 24 hours
temp_file_expires = ExpiresIn.days(7) # 7 days
# Long-lived items
trial_expires = ExpiresIn.weeks(2) # 2 weeks
| Method | Example | Description |
|---|---|---|
ExpiresIn.seconds(n) |
ExpiresIn.seconds(30) |
n seconds from now |
ExpiresIn.minutes(n) |
ExpiresIn.minutes(15) |
n minutes from now |
ExpiresIn.hours(n) |
ExpiresIn.hours(1) |
n hours from now |
ExpiresIn.days(n) |
ExpiresIn.days(7) |
n days from now |
ExpiresIn.weeks(n) |
ExpiresIn.weeks(2) |
n weeks from now |
All methods return a datetime in UTC.
Checking expiration
is_expired
Check if an item has expired:
"""Check expiration status."""
from pydynox import Model, ModelConfig
from pydynox.attributes import StringAttribute, TTLAttribute
class Session(Model):
model_config = ModelConfig(table="sessions")
pk = StringAttribute(hash_key=True)
expires_at = TTLAttribute()
session = Session.get(pk="SESSION#123")
if session:
# Check if expired
if session.is_expired:
print("Session has expired")
else:
# Get time remaining
remaining = session.expires_in
if remaining:
hours = remaining.total_seconds() / 3600
print(f"Session expires in {hours:.1f} hours")
is_expired returns:
Trueif the TTL time has passedFalseif not expired or no TTL attribute
expires_in
Get time remaining until expiration:
remaining = session.expires_in
if remaining:
print(f"Expires in {remaining.total_seconds()} seconds")
print(f"Expires in {remaining.total_seconds() / 60} minutes")
else:
print("Already expired or no TTL")
expires_in returns:
timedeltaif not expiredNoneif expired or no TTL attribute
Extending TTL
Use extend_ttl() to push back the expiration:
"""Extend TTL example."""
from pydynox import Model, ModelConfig
from pydynox.attributes import ExpiresIn, StringAttribute, TTLAttribute
class Session(Model):
model_config = ModelConfig(table="sessions")
pk = StringAttribute(hash_key=True)
expires_at = TTLAttribute()
session = Session.get(pk="SESSION#123")
if session and not session.is_expired:
# Extend by 1 hour from now
session.extend_ttl(ExpiresIn.hours(1))
print("Session extended")
This updates both the local instance and DynamoDB in one call.
Real-world example
Session management with TTL:
from uuid import uuid4
from pydynox import Model, ModelConfig
from pydynox.attributes import ExpiresIn, StringAttribute, TTLAttribute
class Session(Model):
model_config = ModelConfig(table="sessions")
pk = StringAttribute(hash_key=True)
user_id = StringAttribute()
expires_at = TTLAttribute()
def create_session(user_id: str) -> Session:
"""Create a session that expires in 24 hours."""
session = Session(
pk=f"SESSION#{uuid4()}",
user_id=user_id,
expires_at=ExpiresIn.hours(24),
)
session.save()
return session
def validate_session(session_id: str) -> bool:
"""Check if session is valid."""
session = Session.get(pk=session_id)
if not session or session.is_expired:
return False
return True
def refresh_session(session_id: str) -> None:
"""Extend session by 24 hours."""
session = Session.get(pk=session_id)
if session and not session.is_expired:
session.extend_ttl(ExpiresIn.hours(24))
How it works
TTLAttributestores datetime as Unix epoch timestamp (number)- DynamoDB's TTL process scans for expired items
- Expired items are deleted automatically (usually within 48 hours)
- No cost for TTL deletions
Warning
Items may remain readable for up to 48 hours after expiration. Always check is_expired in your code if you need strict expiration.
Best practices
- Always check is_expired - Don't rely only on DynamoDB deletion
- Use UTC -
ExpiresInreturns UTC times, keep everything in UTC - Enable TTL on table - TTL won't work without table-level configuration
- Choose the right duration - Too short = bad UX, too long = wasted storage
Next steps
- Attributes - All attribute types
- Models - Model basics
- Hooks - Run code before/after operations