Curiosity

Deletion queue

The deletion queue can be used to "schedule" a node deletion in the future. A background sweeper job picks it up once that time arrives and deletes it. This page explains why, when to use it, and how to inspect the queue.

When to use it

Deferred deletion is most useful for data that is known up-front to have a bounded lifetime:

  • Temporary or scratch data produced by scheduled tasks, ingestion runs, or short-lived analyses, that should be cleaned up automatically once it is no longer needed.
  • Time-bounded data subject to a retention policy — for example, chat transcripts, audit copies, cached search results, or records that must not be kept beyond a specific expiry date.

Queueing a deletion at insert time (or whenever the expiry is known) means the workspace enforces the retention bound on its own, with no extra cron job or maintenance script.

Deferring deletion also gives the workspace two operational properties:

  • Recovery window. A queued deletion can be cancelled before the sweeper runs, so a mistaken delete is recoverable for the length of the grace period.
  • Replication ordering. In replicated workspaces the delay gives every replica a chance to observe the deletion intent before the data is actually gone, which keeps _ChangeLog-driven catch-up consistent.

A queued node is still present in the graph and still answers queries. Only when the sweeper processes the entry does the node — and its content, edges, and index entries — get removed.

On-disk layout

The deletion queue lives in its own RocksDB column family (deletion-queue) alongside the rest of the graph. Each entry is a key with no value; the key encodes both the scheduled time and the UID so that iteration in key order yields entries in due-date order:

key  = yyyyMMddHHmm  (12 bytes, ASCII, UTC)
     + UID128        (16 bytes, raw)
value = (empty)

The 12-byte UTC prefix gives minute-level resolution. Multiple entries for the same UID at different scheduled times are allowed; cancelling a deletion removes every entry that matches the UID regardless of when it was scheduled.

Lifecycle

flowchart LR A[Admin deletes node] --> B[QueueDeletion uid delay] B --> C{Entry in deletion-queue<br/>scheduledFor = now + delay} C -->|grace period| D{Time reaches scheduledFor} D -->|sweeper tick| E[Graph TryDeleteAsync uid] E --> F[Node, edges, content, indexes removed] C -.->|CancelDeletion uid| G[Entry removed,<br/>node stays in graph]

The sweeper (ProcessDueDeletionsAsync) runs as part of the graph's background loop. It iterates the queue oldest-first, stops as soon as it hits an entry whose minute-prefix is later than DateTime.UtcNow, deletes every UID it collected, and only then removes the processed keys. A delete that fails mid-flight is logged and retried on the next sweep — the queue key is the source of truth, not in-memory state.

Inspecting the queue

The admin UI exposes the queue read-only under Manage › Operate › Observability › Deletion Queue. Each row shows:

Column Meaning
UID The 22-char base58 UID of the node scheduled for deletion.
Scheduled for UTC instant at which the entry becomes eligible. The cell shows the viewer's local time; hover for UTC.
When Time remaining until the sweeper picks the entry up. Past-due entries (still waiting for the next sweep tick) are flagged in red; entries due within the hour are flagged in orange.
Node The resolved node label, if the node still exists in the graph.

The view is a snapshot — it does not auto-refresh. Use the refresh button in the page header to re-read the queue.

Empty state

An empty deletion queue is the normal steady state on a healthy workspace. Entries should accumulate only briefly between an admin delete and the next sweeper tick.

What you can't do from this view

The deletion queue page is read-only. There is intentionally no "cancel" button, because cancellation reaches into storage and the right place to recover a mistakenly-deleted node is to restore from backup or, where the node was deleted through a script, re-run the inverse operation. If you find yourself needing to cancel queue entries from the UI, file a feature request rather than working around it.

See also

Referenced by

© 2026 Curiosity. All rights reserved.
Powered by Neko