Stopping cron jobs on a restored project or branch

After a restore, a project's cron jobs keep running against the restored database. Branches start with no jobs. How to pause, review and recreate jobs safely.

What you see

You restored a project to an earlier point, and its cron jobs ran straight away against the restored data. Reminder emails went out again, a billing job charged an old batch, or a sync job pushed stale rows to another system.

Or the opposite: you created a branch, and none of the parent's cron jobs are there.

Why it happens

On SupaHost, pg_cron runs in the instance's postgres database, not inside each project. Jobs are stored there and matched to a project by its database name.

  • Restore. A restore replaces the project's database but keeps its name. The job list isn't part of the project database, so it isn't rolled back. Every job that existed when you started the restore keeps its schedule and runs against the restored data on its next tick. Jobs you deleted after the restore point don't come back.
  • Branch. A branch is a new database with a new name. No jobs are keyed to that name, so the branch has none. That's deliberate: a test copy shouldn't send real emails or call real webhooks.

How to fix it

Before a restore

  1. Open Dashboard → your project → Cron tab and turn Active off for any job with side effects: emails, payments, outbound webhooks, syncs.

  2. Note which jobs you paused, or save them in SQL so you can bring them back later:

    select jobname, schedule, command, active
    from cron.job
    order by jobname;
    
  3. Run the restore from the Backups tab.

After a restore

  1. Check the data looks right, then check the jobs still make sense for it. A job that processes "everything since the last run" may now pick up rows it already handled before.
  2. If a job has a marker table or column (for example last_sent_at), fix it first so the job doesn't redo old work.
  3. Turn Active back on for each job.

If a job already ran and you need it to stop now, turn its Active toggle off, or remove it in SQL:

select cron.unschedule('send-invoice-reminders');

cron.alter_job isn't available on SupaHost, so pausing is done with the Active toggle.

On a branch

Recreate only the jobs you want to test, pointed at safe targets. For example, send webhooks to a test endpoint rather than production:

select cron.schedule(
  'nightly-report',
  '0 2 * * *',
  $$ select net.http_post(
       url := 'https://hooks.example.com/test/nightly-report',
       body := jsonb_build_object('source', 'branch')
     ) $$
);

Unschedule the branch's jobs before you delete the branch. If a job should also exist on the parent project, create it there yourself, because branches don't merge back.

On SupaHost

  • Restores apply to one project. Other projects on the instance and their jobs aren't touched.
  • The database from before the restore is kept for 3 days as p_<project>_pre_restore_<timestamp>. Cron jobs never run against it.
  • The Cron tab shows Recent runs for the last 50 runs, so you can confirm nothing ran while paused.

Updated 11 November 2026 · View as Markdown · Something wrong or missing? Tell us