Skip to content

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);