Scheduled Purge — Keep Only the Last 3 Log Entries¶
This chapter demonstrates pg_relay's deferred event feature: scheduling work to run at a future time, entirely from within the database — no external scheduler required.
Create the purge function¶
The function calls pgrelay.purge() to trim the log. It is SECURITY DEFINER, so it runs as app_user, who was granted EXECUTE on pgrelay.purge() back in One-Time Superuser Setup. The pgrelay role itself does not need that grant.
CREATE FUNCTION purge_logs(p_payload text)
RETURNS void LANGUAGE plpgsql
SECURITY DEFINER
SET search_path = public, pg_temp
AS $$
BEGIN
PERFORM pgrelay.purge(p_keep_quantity := 3);
END;
$$;
GRANT EXECUTE ON FUNCTION purge_logs(text) TO pgrelay;
Register the channel¶
SELECT pgrelay.register(
'purge_log',
'SELECT public.purge_logs($1)',
'Purges pgrelay.log, keeping the 3 most recent entries'
);
Schedule the purge to run in 2 minutes¶
Check the queue — confirm the event is deferred¶
You will see one pending row with run_at roughly 2 minutes in the future and dispatched_at NULL. The Processor's probe ignores rows where run_at > now(), so nothing happens yet.
id | channel | run_at | dispatched_at
-----+-----------+-------------------------------+---------------
... | purge_log | 2026-04-22 12:05:00.000+00 |
Count current log entries¶
You should see around 39 entries from the earlier chapters' work. Make a note of this — it will drop to 4 once the purge runs. The reason it lands on 4, not 3, is the 3 you asked to keep plus 1 new log entry for the purge action itself.
Wait and re-query until the purge fires¶
After 2 minutes, the Processor picks up the purge_log event and runs purge_logs(''). Re-run this until the count drops:
When it reaches 4, the purge has run. Query the remaining entries:
id | channel | status | actioned_at
-----+-----------+--------+----------------------------
... | purge_log | ok | 2026-04-22 12:05:01.123+00
... | ... | ... | ...
... | ... | ... | ...
... | ... | ... | ...
Four rows remain. The purge kept the 3 most recent entries that existed when it ran, then pg_relay wrote a 4th row — the ok entry for the purge_log event itself (written after the action completes). Everything older has been removed.
Continue to How the Events Flow for a diagram summarising everything you have just seen.