# Background runs

A table of 100,000 rows takes about an hour. Instead of waiting on the `CALL`, run it in the background: the
app queues the run, returns at once, and does the work in its own serverless task.

## Start a background run

`run_tool_async` takes the same arguments as [`run_tool`](./enrich-a-table#other-input-combinations-run_tool):

```sql
CALL TOMBA.core.run_tool_async('email_finder', 'CRM.PUBLIC.LEADS',
    {'domain': 'COMPANY_DOMAIN', 'first_name': 'FIRST_NAME', 'last_name': 'LAST_NAME'},
    'LEADS_FOUND', 500000, {'max_credits': 20000});
```

It returns `{run_id, status: 'QUEUED', output_table}`. Company searches have the same form:
`search_companies_async(filters, output_table, max_results)`.

In the Streamlit app, **Run in the background** on the Enrich a table page (and on Find companies) does the
same, and takes you to **History**.

## Follow progress

```sql
SELECT run_id, tool, status, progress_pct, rows_total, rows_expected, charged_usd, message
  FROM TOMBA.core.runs
 WHERE status IN ('QUEUED', 'RUNNING')
 ORDER BY started_at DESC;
```

`progress_pct` is the share of rows done. The **History** page shows the same as progress bars.

## Cancel

```sql
CALL TOMBA.core.cancel_run('<run_id>');
```

A running run stops after the rows it is working on (up to 1,000); a queued run never starts. Rows already done
are kept, and you can [resume](./resume-and-auto-resume) the run later.

## Good to know

- Background runs need the app's `EXECUTE TASK` and `EXECUTE MANAGED TASK` privileges (see
  [Installation](./installation#2-approve-the-connection-and-the-privileges)). Without them, the call explains
  what to approve; regular runs still work.
- The serverless task uses Snowflake compute, billed to your account like any serverless task. Lookups wait
  on the network, so it stays small.
- Runs are processed one at a time, oldest first.
