Retention¶
Notifications, attachments, history, and traces grow forever unless purged:
-- delete terminal notifications older than 30 days (attachments, history,
-- and traces go with them); returns the count
SELECT pgrelay_notifier.purge(interval '30 days');
-- sweep abandoned drafts too
SELECT pgrelay_notifier.purge(interval '7 days', ARRAY['draft']);
-- debug traces usually deserve a shorter retention
SELECT pgrelay_notifier.purge_debug(interval '7 days');
pending and retry notifications are never purgeable — the Processor may still fetch them. Schedule purges with pg_cron, a system cron job, or even a pg_relay SQL channel. Pair with pgrelay.purge() for the audit log itself, which pg_relay_notifier does not touch.
What purge() actually removes¶
Deleting a notification cascades to its attachments (a real foreign key) and sweeps its status_history and debug_trace rows (not foreign-key-enforced, by design — see the Technical Reference for why those two tables have none), including any orphaned rows left by a set_status()/debug_log() call against an id that no longer exists.
Monitoring queries worth wiring up¶
-- notifications stuck pending > 5 minutes (Processor down? channel disabled?)
SELECT * FROM pgrelay_notifier.list_notifications('pending')
WHERE dispatched_at < now() - interval '5 minutes';
-- failure detail histogram, last 24h
SELECT status_detail, count(*)
FROM pgrelay_notifier.list_notifications('failed', now() - interval '1 day')
GROUP BY status_detail ORDER BY count(*) DESC;
-- audit cross-check: notifier vs pg_relay for one message
SELECT * FROM pgrelay.log WHERE payload = '42'::text ORDER BY id;
SELECT * FROM pgrelay_notifier.get_history(42);