Skip to content
Knowledge base

Monitor Supabase pg_cron jobs with a heartbeat

pg_cron records each run in a table nobody reads. Send a heartbeat with pg_net from inside the job, and only a committed run counts as a success.

1. Enable pg_net alongside pg_cron

Both are Postgres extensions you can enable from the Supabase dashboard. pg_cron runs the schedule; pg_net lets SQL make an outbound HTTP request with net.http_get.

2. Create the heartbeat

Add a monitor with Check type Heartbeat (cron), set the interval to the job's period and a grace period for its run time, and copy the ping URL when it is shown.

3. Ping from the same command as the work

Schedule the work and the ping as one command: select cron.schedule('nightly-rollup', '0 3 * * *', $$ call refresh_rollups(); select net.http_get('<your ping URL>'); $$); Supabase's pg_net documentation says HTTP requests are not started until the transaction is committed, so if the work raises an error and rolls back, the ping is never sent and the monitor goes down at the deadline.

4. What this catches, and what it does not

A job that errors, a job that was unscheduled, and a database that was paused or down all stop the pings. The ping URL is a credential, so keep the cron command readable only to roles that need it. Heartbeats are on every plan, Free included, and the same account can watch the project's API from outside with an HTTP check.

Go deeper

The full reference lives in the docs: Heartbeat monitors documentation. Error codes named above are each explained in the error-code reference.