Skip to main content
Any CRDT op sent over WebSocket can include an optional 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

  1. Client sends a WebSocket op with ttl_ms set.
  2. Server applies the op and records expires_at_ms = now + ttl_ms on the CRDT entry.
  3. GC task runs every 5 seconds and calls delete_expired — a single indexed DELETE on PostgreSQL, no-op on sled/in-memory.
  4. Expired entries are removed from storage permanently.
The CRDT continues to function normally until it expires.

Usage

Pass ttlMs 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 + 5s before 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: