/
Cloud Scheduler

Supabase Cron (pg_cron) Guide

Supabase exposes pg_cron, a Postgres extension that runs scheduled jobs directly inside the database using standard cron syntax — useful for periodic SQL maintenance (cleanup, materialized view refreshes) or for triggering a Supabase Edge Function on a schedule via pg_net.

Syntax Notes

Standard 5-field cron syntax passed as the first argument to cron.schedule(), alongside the SQL command to run — jobs are managed via SQL function calls rather than a config file, and are stored in the cron.job table inside the database itself.

Examples

Schedule a nightly cleanup at 2 AM
select cron.schedule(
  'nightly-cleanup',
  '0 2 * * *',
  $ delete from logs where created_at < now() - interval '30 days' $
);
List all scheduled jobs
select * from cron.job;
Unschedule a job by name
select cron.unschedule('nightly-cleanup');

Gotchas

  • The pg_cron extension must be explicitly enabled first (via Database > Extensions in the Supabase dashboard, or `create extension pg_cron`) — cron.schedule() calls fail outright on a project where it hasn't been turned on.
  • pg_cron schedules always run in UTC against the database's own clock, not any per-project timezone setting — the same daylight-saving-offset caveat that applies to most cloud schedulers applies here too.
  • A failed or long-running scheduled job doesn't surface anywhere obvious by default — check the cron.job_run_details table for run history and errors, since there's no dashboard notification for a silently failing scheduled job.

Best Practices

  • Query cron.job_run_details periodically (or wire up alerting on it) rather than assuming a scheduled job succeeded — pg_cron doesn't push failure notifications on its own.
  • Give every scheduled job an explicit, descriptive name (the first argument to cron.schedule()) rather than leaving it to auto-generate one, since that name is needed to unschedule or look it up later.
  • For anything beyond simple SQL maintenance — like calling an external API or an Edge Function — pair pg_cron with the pg_net extension to make an async HTTP request from inside the scheduled job.

Frequently Asked Questions

Do I need to install anything to use pg_cron on Supabase?
You need to enable the pg_cron extension first, either from Database > Extensions in the Supabase dashboard or by running create extension pg_cron via SQL — it isn't enabled by default on a new project.
Can pg_cron trigger a Supabase Edge Function, not just SQL?
Yes, indirectly — combine pg_cron with the pg_net extension to make an outbound HTTP request to your Edge Function's URL from inside the scheduled job, since pg_cron itself only executes SQL directly.
How do I see if a pg_cron job actually ran successfully?
Query the cron.job_run_details table, which logs every execution attempt along with its status and any error message — there's no dashboard alert for a failing job, so this table is the primary way to check.