ttl_ms. The server stores an expires_at_ms timestamp alongside the CRDT value. A background GC task runs every 5 seconds and permanently deletes entries where expires_at_ms < now().
Useful for temporary documents, sessions, short-lived drafts, or any data that should not persist indefinitely.
How it works
- Client sends a WebSocket op with
ttl_msset. - Server applies the op and records
expires_at_ms = now + ttl_mson the CRDT entry. - GC task runs every 5 seconds and calls
delete_expired— a single indexedDELETEon PostgreSQL, no-op on sled/in-memory. - Expired entries are removed from storage permanently.
Usage
PassttlMs as the last argument to any handle method that sends an op:
TTL is attached per-op — not per-CRDT. The last op to set a
ttlMs wins. Sending a new op without ttlMs clears the expiry.GC behavior
- GC interval: 5 seconds
- An entry may live up to
ttl_ms + 5sbefore being deleted. - Deletion is permanent — no tombstone delta is broadcast to subscribers.
- Applies to all CRDT types (GCounter, PNCounter, ORSet, LwwRegister, CRDTMap).
Presence TTL vs CRDT TTL
These are two distinct mechanisms:| Presence TTL | CRDT TTL (ttl_ms) | |
|---|---|---|
| Scope | Per-entry within the Presence CRDT | The entire CRDT entry |
| Expiry check | Client-side, on each value() call | Server-side GC task |
| Storage cleanup | GC publishes tombstone delta | Entry deleted from DB, no broadcast |
| Use case | ”Who’s online” with heartbeats | Temporary documents, sessions |