Working with TTL Indexes

1. Creating TTL Index

AspectDetail
Single fieldMust index a Date field (or array of Dates)
Option{ expireAfterSeconds: N }
db.sessions.createIndex({ lastActive: 1 }, { expireAfterSeconds: 1800 });

2. Setting Expiration Time

PatternForm
Fixed lifetimeexpireAfterSeconds: 86400
Explicit timestampexpireAfterSeconds: 0 + per-doc Date

3. Understanding TTL Monitor Thread

AspectDetail
Interval60 seconds default
ThrottledYes, to avoid impacting workload
LatencyExpiration may lag actual deadline by minutes

4. Using Date Fields for Expiration

ValueBehavior
BSON DateDeletion triggered after expireAfterSeconds beyond date
Array of DatesEarliest date used
Non-DateDocument is not expired

5. Modifying TTL Index

CommandEffect
collMod({index:{name:"idx", expireAfterSeconds: N}})Update interval
Drop+recreateAlternative

6. Removing TTL Behavior

ApproachEffect
Drop indexRemoves expiration entirely
collMod expireAfterSeconds=Very largeEffectively disable

7. Monitoring TTL Deletions

MetricSource
ttl.deletedDocumentsdb.serverStatus().metrics.ttl
ttl.passesSweep cycles count

8. Understanding TTL Limitations

LimitationDetail
CappedNot supported on capped collections
CompoundCannot be compound (single-field only)
PrecisionNot real-time; ~60s sweep
Time seriesUse expireAfterSeconds on collection instead

9. Using TTL with Partial Indexes

AspectDetail
CombineTTL + partialFilterExpression
Use caseExpire only "soft-deleted" docs
db.posts.createIndex(
  { deletedAt: 1 },
  { expireAfterSeconds: 0, partialFilterExpression: { deletedAt: { $exists: true } } }
);

10. Implementing Data Retention Policies

PolicyApproach
Sessions (30 min idle)TTL on lastActive
Logs (90 days)TTL on createdAt; expireAfterSeconds: 7776000
GDPR cooldownSoft delete + partial TTL
Compliance archive$merge to cold storage before TTL