> ## Documentation Index
> Fetch the complete documentation index at: https://docs.delphina.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Snowflake Performance & Tuning

> Size, scale, and monitor your Snowflake warehouse so Delphina queries complete reliably instead of timing out

Once Delphina is [connected to Snowflake](/administration/snowflake), the main thing that
determines whether it feels fast or flaky is how the warehouse behind it is sized and
scaled. This guide covers our learned defaults for sizing, when to scale out versus up, and
how to have Delphina diagnose your specific account.

<Note>
  The right numbers vary a lot by workload. Start with the defaults below, then use the
  [monitoring prompts](#monitoring-for-queueing) to tune from your account's real behavior.
</Note>

## Why the 2-minute target matters

Delphina enforces a **120-second timeout** on every warehouse query. A query that hasn't
returned by then is cancelled and surfaces to the user as a failure.

This cap is deliberate — it acts as a **circuit breaker**. When a warehouse gets slow (a
cluster is saturated, a large scan is running), queries would otherwise sit in Snowflake's
queue and pile up behind each other, with every new query inheriting an ever-growing wait.
Cancelling at 120 seconds bounds how long any single query can hold a warehouse slot, so a
temporary slowdown doesn't cascade into a much longer queue on your side.

The practical implication: **size your warehouse so the queries you care about finish
comfortably under 2 minutes**, including any time spent queued. Queue time and execution
time share the same budget. Repeated timeouts aren't just errors to dismiss — they're the
signal that the warehouse needs to scale.

## The two scaling knobs

Snowflake gives you two independent controls, and they fix two different problems:

| Symptom                                                   | Knob                            | What to change                                                                  |
| --------------------------------------------------------- | ------------------------------- | ------------------------------------------------------------------------------- |
| A single query is slow (large scans, complex joins)       | **Warehouse size** — scale *up* | Bump `WAREHOUSE_SIZE` one step (e.g. `SMALL` → `MEDIUM`) and re-measure         |
| Queries are fast alone but queue up under concurrent load | **Multi-cluster** — scale *out* | Raise `MAX_CLUSTER_COUNT` so Snowflake adds clusters to run queries in parallel |

<Tip>
  **Start by scaling out, not up.** Delphina issues many independent queries concurrently
  (exploration, validation, pipeline steps), so the common failure mode is *queueing*, not a
  single query being too big. Adding clusters removes the queue; upsizing only helps if
  individual queries are genuinely too slow.
</Tip>

### Recommended starting point

A dedicated, multi-cluster warehouse for Delphina:

```sql theme={null}
-- Adjust names to your environment. Start here, then tune from measured behavior.
CREATE WAREHOUSE IF NOT EXISTS DELPHINA_WH
  WAREHOUSE_SIZE       = 'SMALL'   -- smallest size that keeps important queries under ~90s
  MIN_CLUSTER_COUNT    = 1
  MAX_CLUSTER_COUNT    = 3         -- scale out to absorb concurrent Delphina queries
  SCALING_POLICY       = 'STANDARD'
  AUTO_SUSPEND         = 60        -- seconds idle before suspend (cost control)
  AUTO_RESUME          = TRUE      -- resume automatically on the next query
  INITIALLY_SUSPENDED  = TRUE;
```

* **`WAREHOUSE_SIZE = 'SMALL'`** — the smallest size that keeps your important queries under
  \~90s (leaving headroom below the 120s cutoff). Go larger only if monitoring shows
  individual queries running long.
* **`MAX_CLUSTER_COUNT`** is your concurrency ceiling. If monitoring shows sustained
  queueing, raise this before touching size.
* **`AUTO_SUSPEND = 60`** keeps costs down between bursts without cold-starting on every
  query.
* **Use a dedicated warehouse for Delphina** rather than sharing one with human analysts or
  ETL. It isolates Delphina's concurrency behavior and makes the monitoring queries below
  clean to interpret.

### Parallel warehouses (advanced)

If different Delphina workloads have very different query profiles — cheap interactive
queries versus heavy pipeline scans — consider **separate warehouses per workload** so a run
of heavy queries can't starve interactive ones. Each is sized and scaled independently.
Start with a single multi-cluster warehouse and only split if monitoring shows contention.

## Monitoring for queueing

You don't need to build dashboards — **ask Delphina**. It has read access to your Snowflake
query history and can identify its own service-account queries and summarize their runtime
and queueing behavior.

<Note>
  This requires query-history access. Delphina's full-history monitoring reads
  `SNOWFLAKE.ACCOUNT_USAGE.QUERY_HISTORY`, which needs the `IMPORTED PRIVILEGES` grant from
  [Step 3 of the connection guide](/administration/snowflake#step-3-grant-access-to-query-history).
  Without it, monitoring falls back to a 7-day, service-account-only window.
</Note>

To run the full diagnosis and get a concrete scale-out-vs-scale-up recommendation, paste
this prompt into a Delphina chat:

```
I want to diagnose whether our Snowflake warehouse is sized and scaled correctly for
Delphina, and get a specific recommendation. Please do the following as one analysis:

1. Look at the Snowflake query history tables and work out the logic to identify recent
   queries made by Delphina's service account (i.e. our service account).

2. For those queries over the past month, summarize runtime and queueing behavior:
   - queue time vs. execution time (totals and percentiles, e.g. p50/p95)
   - how often queries approach or exceed the 120-second mark (Delphina cancels queries at
     120s, so treat that as the SLO)
   - how queueing correlates with concurrent load and time of day

3. Analyze the overlap between concurrently running queries — how many Delphina queries are
   typically in flight at once, and whether queue time rises with that concurrency.

4. Based on all of the above, tell me which will reduce overall queuing more: a larger
   warehouse (scale up) or more horizontal scaling / more clusters (scale out). The rule of
   thumb: high concurrency/overlap with acceptable per-query runtime → scale out; low
   overlap but long individual runtimes near the 120s limit → scale up. Give a concrete
   recommendation (target warehouse size and/or MAX_CLUSTER_COUNT) with the evidence behind
   it.
```

### Reading the results

| What the data shows                                                   | What to do                                                                                   |
| --------------------------------------------------------------------- | -------------------------------------------------------------------------------------------- |
| High queue time, low execution time (high query overlap)              | Raise `MAX_CLUSTER_COUNT` — **scale out**                                                    |
| Low queue time, high execution time near the 120s limit (low overlap) | Bump `WAREHOUSE_SIZE` — **scale up**, or ask Delphina to help optimize the offending queries |
| Both high                                                             | Do both, scaling out first                                                                   |
