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
Open Dashboard → your project → Cron tab and turn Active off for any job with side effects: emails, payments, outbound webhooks, syncs.
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;Run the restore from the Backups tab.
After a restore
- 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.
- 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. - 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.