Skip to content

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 timestamp
  • ExpiresIn helper - easy time calculations
  • is_expired property - check if item expired
  • expires_in property - get time remaining
  • extend_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:

  • True if the TTL time has passed
  • False if 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:

  • timedelta if not expired
  • None if 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

  1. TTLAttribute stores datetime as Unix epoch timestamp (number)
  2. DynamoDB's TTL process scans for expired items
  3. Expired items are deleted automatically (usually within 48 hours)
  4. 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

  1. Always check is_expired - Don't rely only on DynamoDB deletion
  2. Use UTC - ExpiresIn returns UTC times, keep everything in UTC
  3. Enable TTL on table - TTL won't work without table-level configuration
  4. Choose the right duration - Too short = bad UX, too long = wasted storage

Next steps