Skip to content

How Events Flowed — Summary

For each INSERT INTO records:

INSERT INTO records
    → records_after_insert trigger
        → pgrelay.notify('json_record', row_json)          [event 1]
        → pgrelay.notify('audit_action', NEW_RECORD)       [event 2]

Processor runs event 1: insert_json_record → INSERT INTO records_json
    → records_json_after_insert trigger
        → pgrelay.notify('audit_action', NEW_JSON_RECORD)  [event 3]

Processor runs event 2: insert_audit_record → INSERT INTO records_audit
Processor runs event 3: insert_audit_record → INSERT INTO records_audit

For each UPDATE records:

UPDATE records
    → records_after_update trigger
        → pgrelay.notify('json_record', row_json)             [event 1]
        → pgrelay.notify('audit_action', RECORD_UPDATED.  )   [event 2]

Processor runs event 1: insert_json_record → UPDATE records_json (UPSERT conflict)
    → records_json_after_update trigger
        → pgrelay.notify('audit_action', UPDATED_JSON_RECORD) [event 3]

Processor runs event 2: insert_audit_record → INSERT INTO records_audit
Processor runs event 3: insert_audit_record → INSERT INTO records_audit

Notice that neither trigger function ever calls the other directly. Every step of this chain — from the original insert, through the JSON snapshot, to both audit entries — passes through pg_relay, and every step gets its own row in pgrelay.log.


Continue to Cleaning Up to remove everything this example created.