TTL
Every frame carries a TTL (time-to-live) that sets how long the store keeps
it. The default is forever. A frame’s TTL is fixed when it is appended and
never changes afterward.
Kinds
| TTL | Query form | Meaning |
|---|---|---|
| Forever | forever (default) | Kept indefinitely. |
| Ephemeral | ephemeral | Never written to the store. Only readers following live at the moment of the append see it. |
| Time | time:<ms> | Kept for <ms> milliseconds after the frame’s creation, then removed. |
| Last | last:<n> | Retains only the newest n frames on the frame’s topic (n >= 1); older frames on that topic are removed. |
Setting a TTL
From Nushell, pass --ttl to .append:
"hello" | .append greeting # forever (default){tick: true} | .append clock --ttl ephemeral{level: "debug"} | .append logs --ttl time:60000 # 60s$state | .append game.score --ttl last:1 # keep only the latestOver HTTP, set the ttl query parameter on the append endpoint
(?ttl=last:1). The wire forms are exactly the query strings in the table
above.
How each kind behaves
foreveris the default, and the right choice for anything another part of the system reads back later.ephemeralframes are broadcast but never persisted, so they never appear in.cathistory or on replay. Use them for liveness signals where a missed frame does not matter.time:<ms>frames expire relative to their own creation timestamp. A read never returns an expired frame, so expiry is immediate as far as any reader is concerned. A background sweeper then removes them from disk. It wakes at most once per sweep interval,xs serve --ttl-sweep, default one second, and removes a bounded batch each time, so clearing a large backlog takes several passes. No read has to touch a frame for it to be removed.last:<n>schedules a per-topic garbage collection when a frame is appended to a topic already at its limit: the store keeps thenmost recent frames on that topic and removes the rest. Removal is asynchronous and batched, so a topic can briefly hold more thannframes on disk, and trimming a large overflow takes several passes. Reads are unaffected — they return whatever is stored. This is retention by topic, not by frame, so it affects every frame that shares the topic.