Skip to content

Retention and Cleanup

Nothing purges automatically. Runs, raw results, run configuration, and evaluations all grow without bound until you delete from them yourself. Call the purge function whenever suits you — from the same scheduler that runs your checks, or by hand:

-- preview first — counts exactly what would be deleted, deletes nothing
SELECT * FROM pghf.purge_results_before(now() - interval '90 days', p_dry_run => true);

-- then actually delete it
SELECT * FROM pghf.purge_results_before(now() - interval '90 days');

This deletes every run older than the cutoff you supply; everything that belongs to those runs — raw results, run configuration, evaluations — is deleted automatically along with them, so nothing else needs cleaning up separately. Catalog data (checks, suites, thresholds, and so on) is never touched by this — only execution history is ever in scope. This is an ordinary operator action, not a privileged one: it uses your own role's permissions on the underlying tables, the same as running the collection engine itself does. Even a dry run needs read permission on the execution-history tables (not open to everyone by default — see The Access Model); an actual purge additionally needs delete permission.

For a large first-ever cleanup

If you're purging months of history that's never been cleaned up before, deleting everything in one single statement can mean one very long-running transaction — heavy write-ahead log generation, a lock held on the runs table for the entire duration, and a large amount of cleanup work left behind for PostgreSQL afterwards. A batched version of the purge function exists for exactly this situation — it deletes in smaller batches, committing (and reporting its progress) after each one:

CALL pghf.purge_results_before_batched(now() - interval '90 days', p_batch_size => 10000);

Same cutoff and dry-run behaviour as the plain purge function, just invoked as a standalone CALL rather than a function, since it needs to commit partway through its own work — which a function isn't able to do. Use this batched version for that first big cleanup; the plain function is perfectly fine for routine, already-small, ongoing purges afterwards.

One more table with its own clock: the notification outbox (pghf.notification_log) is deliberately not touched by the run purges — a record that you notified on something should outlive the run it fired from — so prune it separately, on your own schedule, with pghf.purge_notification_log_before().

Continue to Blackout Windows.