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

# SQL & queries

> Run SQL against Allium's blockchain data, save reusable Explorer queries, and fetch results.

export const chainCount = '85+';

Query {chainCount} chains of historical blockchain data with SQL. Query execution is **asynchronous**: you queue a run, get a `run_id` back, then fetch results with `get_query_run_results`.

<Tip>
  Call `get_skill(name="sql-optimization")` once at the start of a SQL session. Allium's Snowflake tables are large; the skill covers the partition and clustering rules that keep a query from scanning a full chain. See [Skills](/ai/mcp/tools-reference/skills).
</Tip>

## Available tools

| Tool                    | Description                                                             |
| :---------------------- | :---------------------------------------------------------------------- |
| `run_sql_query`         | Queue an ephemeral, throwaway SQL query. Returns a `run_id`             |
| `create_explorer_query` | Save a SQL query in Explorer. Optionally runs it immediately            |
| `get_explorer_query`    | Retrieve a saved query — SQL, row limit, parameters, tags, URL, visuals |
| `update_explorer_query` | Change a saved query's SQL, title, compute profile, or tags             |
| `list_explorer_queries` | List saved queries, filtered by title search or tags                    |
| `run_explorer_query`    | Run a saved query by ID, with optional template parameters              |
| `delete_explorer_query` | Permanently delete a saved query                                        |
| `get_query_run_results` | Fetch (or poll for) the results of a run                                |
| `list_compute_profiles` | List the org's compute profiles and their current queue depth           |

## The execution model

Every query runs through the same two-step flow.

<Steps>
  <Step title="Queue the run">
    `run_sql_query` and `run_explorer_query` return immediately with a `run_id` and `status: "queued"`. `create_explorer_query(run_on_creation=true)` returns `status: "created"` and puts the run's ID in **`initial_run_id`**. None of them return rows.
  </Step>

  <Step title="Fetch the results">
    Call `get_query_run_results` with the `run_id`. Pass `poll_timeout_seconds` to block until the run finishes; omit it for a single non-blocking status check.
  </Step>
</Steps>

```json theme={null}
{
  "name": "get_query_run_results",
  "arguments": {
    "run_id": "<RUN_ID>",
    "poll_timeout_seconds": 120,
    "row_limit": 500
  }
}
```

| Parameter              | Default | Notes                                                                                   |
| :--------------------- | :------ | :-------------------------------------------------------------------------------------- |
| `run_id`               | —       | Returned by any of the run tools                                                        |
| `poll_timeout_seconds` | `null`  | Poll up to this many seconds, max **180**. Omit, `null`, or `0` checks once and returns |
| `row_limit`            | `50`    | Rows returned to the agent. Pass `null` or `0` for no tool-side truncation              |

The response carries the SQL, the column metadata, the rows, the run status, and the run's cost in Explorer Units.

<Note>
  Two separate caps apply, and the query-side one depends on which tool you used:

  * **`run_sql_query`** caps the run at **1,000 rows**.
  * **Saved queries** (`create_explorer_query` / `run_explorer_query`) cap at the query's own row limit — **10,000** by default, and your organization can be configured higher.
  * Either way, the **tool response** truncates to `row_limit` (50 by default) so a large result doesn't flood your agent's context.

  Raise `row_limit` deliberately. See [Billing & limits](/ai/mcp/tools-reference/billing-and-limits).
</Note>

## Choosing a tool

<CardGroup cols={2}>
  <Card title="run_sql_query" icon="bolt">
    **Throwaway.** Sample rows, check distinct values, answer one ad-hoc question. The run isn't saved and can't back a chart.
  </Card>

  <Card title="create_explorer_query" icon="floppy-disk">
    **Reusable.** Anything that feeds a visual or dashboard, needs a permalink, or is expensive enough to re-run later.
  </Card>
</CardGroup>

<Warning>
  Don't run SQL with `run_sql_query` and then save the same SQL with `create_explorer_query` — that bills the compute twice. If the result might be reused, start with `create_explorer_query(run_on_creation=true)`.
</Warning>

## Run ad-hoc SQL

```json theme={null}
{
  "name": "run_sql_query",
  "arguments": {
    "sql": "SELECT COUNT(*) FROM ethereum.raw.transactions WHERE block_timestamp > CURRENT_DATE - 1",
    "compute_profile": "2x"
  }
}
```

**Returns:** `{ "run_id": "...", "status": "queued", "sql": "..." }`

## Save and run Explorer queries

### Create

```json theme={null}
{
  "name": "create_explorer_query",
  "arguments": {
    "title": "Daily DEX volume by chain",
    "sql": "SELECT DATE(block_timestamp) AS date, chain, SUM(usd_amount) AS volume FROM crosschain.dex.trades WHERE block_timestamp >= {{start_date}} GROUP BY 1, 2",
    "tags": ["dex", "volume"],
    "run_on_creation": true
  }
}
```

**Returns:** a `query_id`, the query's Explorer URL, and — when `run_on_creation` is true — a `run_id`.

### Run

Template parameters use `{{parameter_name}}` syntax in the saved SQL.

```json theme={null}
{
  "name": "run_explorer_query",
  "arguments": {
    "query_id": "<QUERY_ID>",
    "parameters": { "start_date": "2026-01-01" }
  }
}
```

### Update, list, delete

`update_explorer_query` takes a `query_id` plus only the fields you want to change — everything else is preserved. `list_explorer_queries` accepts `search` (title match), `tags` (returns queries carrying at least one), and `limit` (default 50). `delete_explorer_query` is permanent.

<Tip>
  Tag queries that belong to the same dashboard or topic, then use the `tags` filter to find them again in a later session.
</Tip>

## Compute profiles

Each compute profile maps to a dedicated Snowflake warehouse sized as a speed multiplier — `1x`, `2x`, `4x`, `8x`, `16x` — with its own queue, shared org-wide but isolated from other profiles.

```json theme={null}
{ "name": "list_compute_profiles", "arguments": {} }
```

Each entry returns an `identifier`, `is_default`, and live queue state:

| Field     | Meaning                                            |
| :-------- | :------------------------------------------------- |
| `queued`  | Queries waiting to start on this profile, org-wide |
| `running` | Queries currently executing, org-wide              |

Pass a profile's `identifier` as the `compute_profile` argument to `run_sql_query`, `run_explorer_query`, or `create_explorer_query`. Prefer a profile with a low `queued` count — a bigger warehouse that's busy can start later than a smaller idle one. Omit `compute_profile` to use the profile where `is_default` is true.

## Related resources

<CardGroup cols={2}>
  <Card title="Find the right tables" icon="magnifying-glass" href="/ai/mcp/tools-reference/knowledge">
    Search schemas, docs, and Terminal dashboards first
  </Card>

  <Card title="Chart the results" icon="chart-mixed" href="/ai/mcp/tools-reference/dashboards">
    Turn a saved query into visuals and dashboards
  </Card>

  <Card title="Billing & limits" icon="receipt" href="/ai/mcp/tools-reference/billing-and-limits">
    Explorer Units, row caps, and timeouts
  </Card>

  <Card title="Data Catalog" icon="database" href="/historical-data/overview">
    Browse every schema available to SQL
  </Card>
</CardGroup>
