# 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.

Source: https://supahost.app/kb/stop-cron-after-restore · Updated 2026-11-11

## 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:

   ```sql
   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:

```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:

```sql
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.

## Related

- [Restoring a project](/docs/platform/restore)
- [Branching](/docs/platform/branching)
- [Scheduled jobs with pg_cron](/docs/cron-queues/cron)
- [How long does a restore take?](/kb/how-long-restore-takes)
