# Cache and budgets

## Result cache

When the same lookup (same tool, input and options) was done recently, the app reuses that result instead of
calling Tomba again. It is **instant and free**: no API call, no credit, no charge.

- Results are reused for **30 days** by default (setting `cache_days`, 0 to 365; 0 turns the cache off).
- Cached rows have `SOURCE = 'cache'` in the output table, and single lookups return `"source": "cache"`.
- Only real answers are cached (`found` and `not_found`). Errors are always retried.

```sql
CALL TOMBA.core.set_setting('cache_days', '7');      -- app_admin
CALL TOMBA.core.clear_cache('email_verifier');       -- app_admin; '' clears every tool
```

Lower `cache_days` when freshness matters, for example for email verification before a campaign.

## Credit limit per run

Add `max_credits` to a run's options. The run is sized so it **never goes over**: it stops before a batch of
rows could exceed the limit, with status `PARTIAL`.

```sql
CALL TOMBA.core.run_tool('domain_search', 'CRM.PUBLIC.ACCOUNTS', {'domain': 'WEBSITE'}, 'ACCOUNT_EMAILS', 10000,
                         {'emails_per_domain': 20, 'max_credits': 5000});
```

The limit counts the worst case per row (for example 2 credits per domain for 20 emails, or +5 per phone with
`enrich_mobile`), so the actual spend is usually lower. [Resume](./resume-and-auto-resume) the run to
continue past the limit.

## Monthly budget

Cap all runs in a calendar month (UTC), in Tomba credits:

```sql
CALL TOMBA.core.set_setting('monthly_credit_budget', '100000');   -- app_admin; 0 = no limit
```

When the budget is reached, runs stop as `PARTIAL` and resume automatically when the next month starts. The
Overview page of the Streamlit app shows how much of the budget is used.

<Callout type="info">
    Credits are what Tomba charges per lookup; see [Pricing and
    limits](./pricing-and-limits) for their price and the credits each tool
    uses.
</Callout>
