Script Valley
MongoDB: Complete Course
Indexing and Query PerformanceLesson 3.5

MongoDB TTL indexes: auto-expiring documents explained

TTL index creation, expireAfterSeconds, background cleanup thread, TTL index limitations, session storage use case, partial filter indexes

Automatic document expiry with TTL

TTL index expiry timeline

A TTL (Time-To-Live) index automatically deletes documents once a configurable number of seconds has passed since a specified Date field. MongoDB's internal background thread scans TTL indexes every 60 seconds and removes all expired documents. This makes TTL indexes the cleanest solution for sessions, OTP tokens, password reset links, rate-limit counters, and any other time-bounded data.

// Documents expire 1 hour after their createdAt Date value
await db.collection('sessions').createIndex(
  { createdAt: 1 },
  { expireAfterSeconds: 3600 }
)

await db.collection('sessions').insertOne({
  userId: 'u1',
  token: 'eyJhbGci...',
  createdAt: new Date()  // MUST be a BSON Date, not a string
})

// Expire at a specific future timestamp instead of a duration
await db.collection('flash_sales').createIndex(
  { expireAt: 1 },
  { expireAfterSeconds: 0 }  // expire at the exact Date stored in expireAt
)
await db.collection('flash_sales').insertOne({
  name: 'Black Friday',
  expireAt: new Date('2024-12-01T23:59:59Z')
})

Important limitations

TTL indexes only apply to fields of BSON Date type or arrays of Dates. They cannot be compound indexes. Deletion timing is approximate — the background thread runs every 60 seconds, so a document may persist up to 60 seconds past its expiry time. Always add application-level expiry checks for any security-sensitive validation such as session tokens or one-time codes.