# Schedules

A schedule keeps a table enriched. At each scheduled time, the app looks up **only the rows added since the
last run** and appends them to the output table. Rows already done are never looked up or charged again.

Creating and changing schedules needs the `app_admin` role.

## Create a schedule

```sql
CALL TOMBA.core.create_schedule(
    'DAILY_LEADS',                          -- name
    'email_finder',                         -- tool
    'CRM.PUBLIC.LEADS',                     -- input table
    {'domain': 'COMPANY_DOMAIN', 'full_name': 'CONTACT_NAME'},   -- columns
    'LEADS_ENRICHED',                       -- output table
    '0 6 * * *',                            -- when (CRON, UTC)
    {'max_credits': 1000});                 -- options, plus an optional credit limit per run
```

The columns and options work as in [`run_tool`](./enrich-a-table#other-input-combinations-run_tool). The
Streamlit app creates schedules from the last step of **Enrich a table**.

## When it runs

`cron` has 5 fields (minute, hour, day of month, month, day of week), in **UTC**. Schedules run at most hourly,
so the minute field must be a single minute.

| Schedule                  | `cron`         |
| ------------------------- | -------------- |
| Every day at 06:00 UTC    | `0 6 * * *`    |
| Every Monday at 07:30 UTC | `30 7 * * 1`   |
| Every hour                | `0 * * * *`    |
| Weekdays at 18:00 UTC     | `0 18 * * 1-5` |

## Manage schedules

```sql
CALL TOMBA.core.list_schedules();                  -- every schedule and its last run
CALL TOMBA.core.pause_schedule('DAILY_LEADS');
CALL TOMBA.core.resume_schedule('DAILY_LEADS');
CALL TOMBA.core.run_schedule('DAILY_LEADS');       -- run it now
CALL TOMBA.core.drop_schedule('DAILY_LEADS');      -- the output table stays
```

Each scheduled run appears in `TOMBA.core.runs` as `schedule:<NAME>`.

## Good to know

- Schedules run on serverless compute, billed to your account like any serverless task. A run with no new
  rows finishes in seconds.
- Use `max_credits` to cap each run, and the [monthly budget](./cache-and-budgets#monthly-budget) to cap them
  all.
- Schedules need the app's task privileges (see [Installation](./installation#2-approve-the-connection-and-the-privileges)).
