Using FaunaDB TTL to Automatically Expire Documents
Learn how to enable FaunaDB’s TTL feature: set a ttl_field on a collection, store expiration as Unix microseconds, and let the background sweep delete documents automatically.
02 Aug 2026, 10:33 UTC

Quick answer
FaunaDB can delete a document automatically when a timestamp you store in the document passes. Enable this by creating a collection with a ttl_field that points to the field holding the expiration time (Unix epoch in microseconds). When the sweep reaches that time, FaunaDB removes the document.
How it works – a worked example
The following FQL snippet shows the three steps: create a collection that knows which field holds the TTL, insert a document with a future expiration timestamp, and verify that the document disappears after the time passes.
// 1. Create a collection named "Logs" that will watch the "expiresAt" field
CreateCollection({
name: "Logs",
ttl_field: "expiresAt"
})
// 2. Insert a log entry that should expire in 10 seconds
Let({
now: Now(),
tenSecLater: TimeAdd(now, 10, "seconds"),
expiresAtMicros: TimeToMicros(tenSecLater)
},
Create(Collection("Logs"), {
data: {
message: "temporary log",
expiresAt: expiresAtMicros
}
})
)
// 3. After waiting >10 seconds, check that the doc is gone
Let({
docRef: Document(Collection("Logs"), "")
},
If(Exists(docRef), "present", "removed")
)
Explanation:
CreateCollectiondefinesttl_fieldas the attribute FaunaDB will read for each document in that collection.- The expiration time must be a number representing Unix epoch microseconds. FaunaDB provides
TimeToMicrosto convert aTimevalue correctly. - FaunaDB runs a background sweep that scans documents; when the stored timestamp is less than or equal to the sweep’s current time, the document is queued for deletion. The sweep runs every few seconds, so removal is eventual – typically within a couple of seconds after the timestamp, but not guaranteed to be instantaneous.
- The final
Letblock shows a simple verification pattern: after you wait past the target time,Existsreturns false and the conditional yields "removed". In practice you would poll or use a streaming query to observe the change.
Limits and common pitfalls
Timing guarantees
The TTL sweep is eventual; do not rely on it for security‑critical data that must be purged at an exact moment. If you need immediate removal, issue an explicit Delete after your business logic confirms the timestamp has passed.
Timestamp format
Two frequent mistakes cause the sweep to ignore a document:
- Storing the timestamp as a string (e.g., "1730000000000000") instead of a number.
- Using milliseconds or seconds instead of microseconds. FaunaDB expects microseconds; a value that is 1,000× too small will appear to expire far in the future, while a value that is 1,000× too large will appear to have already expired.
To avoid these, always generate the value with TimeToMicros(TimeAdd(Now(), offset, "seconds")) or a equivalent calculation in your driver.
Field indexing and performance
The sweep reads the ttl_field on every document in the collection during each cycle. If the field is not indexed, each sweep can become a full collection scan, degrading performance on large collections. While FaunaDB automatically indexes the field when you set ttl_field at creation time, adding the field later (AddField) does not create the index. In that case you must either:
- Create a new collection with the correct
ttl_fieldand migrate existing documents, or - Manually create an index on the field and ensure the sweep can use it (FaunaDB will use any index that matches the field).
Changing the TTL field
If you alter ttl_field on an existing collection, the sweep continues to read the original field unless you rewrite every document to place the timestamp in the new field. The safest approach is to:
- Create a new collection with the desired
ttl_field. - Use
MapandCreateto copy documents, converting the timestamp if needed. - Swap application traffic to the new collection and delete the old one.
Practical verification steps
To confirm TTL is working in a development environment:
- Create a test collection with a TTL field as shown above.
- Insert a document with an expiration set a few seconds ahead (e.g., 5 seconds).
- Immediately run
Paginate(Collection("TestColl")); you should see the document. - Wait >10 seconds, then run the same pagination query; the document should no longer appear.
- Optionally, use the
Eventuallypattern or a simple polling loop withExiststo assert the transition from "present" to "removed".
If the document persists beyond the expected window, double‑check that the timestamp is a number in microseconds and that the collection’s ttl_field matches the field name you used.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.