novadocs
Concepts

Concepts

Retention

Age-based retention advances the trim watermark for you; history goes logically at once and physically later; deleting a stream

A per-stream trim watermark bounds history in nova: everything below it is gone the moment the watermark moves, and the auditor reclaims the bytes later. This page covers age-based retention, what "gone" means for readers and for your bill, and stream deletion; the watermark's explicit form is the Trim verb.

Age-based retention

A stream's retention_max_age_ms (set at creation or copied from the bucket's defaults, and changeable at any time with ReconfigureStream — including back to unbounded) arms a background retention duty that resolves now − max_age against record time, advances the watermark to the first record younger than that, reclaims what fell below, and re-arms itself for the next expiry. Granularity is seconds, independent of any object boundary: a quiet stream trims on time exactly like a busy one.

Retention reads record time as wall clock. That is why a stream cannot combine age retention with uncapped timestamping (an application-scale stamp would mis-trim silently), and nova refuses the combination at create and update, on streams and bucket defaults alike. Client-supplied stamps under the default client-prefer rule are capped at arrival time, so they are safe with age retention.

Seven days of history
nova stream create --bucket logs --key api --retention-max-age 168h
curl -s -X POST localhost:8080/v1/streams/logs/api -d '{"retention_max_age_ms":604800000}'

Age retention trims through the leader like an explicit trim, so the leader's watermark stays exact. A stream with no age bound keeps history until you trim it.

retention_max_bytes exists on the wire and in bucket defaults but the retention duty acts on age; do not rely on a byte bound to reclaim history today.

What "gone" means

Deletion is two things at two speeds:

  1. Logically, at once. The watermark is a metadata write; from that instant no reader can see the records below it.
  2. Physically, later. The auditor reclaims settled objects that lie wholly below the watermark. Because a stream's settled objects are contiguous by sequence number, reclamation drops whole front objects as the watermark passes them; at most one boundary object straddles. Every reclaim waits out the read grace (--auditor-read-grace, default 10 m) between an object's last reference dying and its physical delete, so a reader mid-fetch is never cut off. Transit bundles shared with other streams are reaped once every stream's extents in them are dead.

For cost, that means history you keep costs object-storage prices for as long as you keep it, and history you trim stops costing once the auditor has reclaimed it: minutes, not instantly, and longer when the auditor is behind. Backlog age is the signal to watch; the duties and their tuning are in auditor duties.

Deleting a stream

DeleteStream removes the stream itself. Nova routes it to the stream's leader, which fences the stream, drains its writers, and tombstones the record; on return the stream is gone for every caller (appends, reads, and subscriptions fail with not-found) while physical reclamation runs asynchronously. Deleting is idempotent: deleting an already deleted stream succeeds; deleting one that never existed is not-found.

A stream recreated at the same (bucket, key) afterwards is a new stream with a fresh ID and an empty history; nothing of the old one is visible through the new address.

err := c.DeleteStream(ctx, addr)
nova stream delete nova://demo/events
curl -s -X DELETE localhost:8080/v1/streams/demo/events

A bucket can be deleted only when no streams live in it.

Source documents

  • docs/adr/0002-trim-watermark-retention.md
  • docs/design/000-decisions.md
  • proto/nova/v1/dataplane.proto
  • client/client.go

On this page