> For the complete documentation index, see [llms.txt](https://docs.onelens.cloud/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.onelens.cloud/integrations/cloud-and-cost-sources/connecting-to-snowflake.md).

# Connecting to Snowflake

Connect your Snowflake account to OneLens for cost intelligence, warehouse optimization, query and data optimization, and AI cost governance — using a read-only service user and Snowflake's built-in u

## TL;DR

**What this does:** Connects your Snowflake account to OneLens for four things — where spend went, whether warehouses are sized right, which workloads and tables create avoidable cost, and what your Cortex AI agents, functions, and search services are consuming.

**Time required:** \~20 minutes

**Who you need:** A user with `ACCOUNTADMIN` to run the setup script. `ORGADMIN` must be enabled once at the org level for contracted-cost data. One DevOps or data-platform engineer to run the script.

**What OneLens reads:** Read-only `SELECT` on views in Snowflake's built-in `SNOWFLAKE.ACCOUNT_USAGE` and `SNOWFLAKE.ORGANIZATION_USAGE` schemas, granted through named Snowflake database roles. Your production data, tables, and rows are never accessed.

{% hint style="warning" %}
**Changed in this version.** The setup script no longer uses `GRANT IMPORTED PRIVILEGES ON DATABASE SNOWFLAKE`. It now grants three named Snowflake database roles instead — which is what Snowflake itself recommends — and excludes the security-related views entirely. If you onboarded with the earlier script, see [Migrating from the previous grant model](#appendix-migrating-from-the-previous-grant-model). Your integration keeps working either way.
{% endhint %}

## What You'll Get Once Connected

The integration covers four capability areas. Each answers a different question.

### Cost Intelligence — where did Snowflake spend go?

| Capability                               | What it does                                                                                          |
| ---------------------------------------- | ----------------------------------------------------------------------------------------------------- |
| **Unified Cost Explorer**                | Snowflake spend in one view alongside AWS, GCP, Azure, OCI, and your other providers                  |
| **Contracted-Cost Reporting**            | Dollar cost at your negotiated rate, not just credits, via `ORGANIZATION_USAGE`                       |
| **Compute / Storage / Serverless Split** | Separates warehouse credits, storage, cloud services, and each serverless feature                     |
| **Cost Allocation by Tag**               | Break spend down by warehouse, user, role, or query tag (team / service / env)                        |
| **Anomaly Detection**                    | Alerts on unusual credit consumption, cross-checked against Snowflake's own `ANOMALIES_DAILY` signals |
| **Budget Tracking**                      | Budgets per warehouse, team, or environment with run-rate alerts                                      |
| **Data Transfer Cost Visibility**        | Egress and cross-region transfer cost, which is easy to miss on the invoice                           |

### Warehouse Optimization — are warehouses configured and sized correctly?

| Capability                           | What it does                                                                                                                 |
| ------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------- |
| **Load-Based Right-Sizing**          | Uses actual running vs. queued load, not just credit totals, to recommend a size                                             |
| **Scale-Up vs. Scale-Out Diagnosis** | Distinguishes *queries are too slow* (size up) from *queries are waiting* (add clusters) from *capacity is idle* (size down) |
| **Concurrency Analysis**             | Peak vs. average concurrent load per warehouse per hour                                                                      |
| **Idle Warehouse Detection**         | Flags warehouses missing auto-suspend or with long suspend windows, and quantifies idle credits                              |
| **Spill Detection**                  | Flags warehouses where queries spill to local or remote storage — the clearest signal a warehouse is undersized              |
| **Queue Analysis**                   | Separates overload queuing from provisioning queuing, which have different fixes                                             |
| **Resize & Suspend History**         | Correlates configuration changes with cost changes, so you can see whether a change worked                                   |

### Query & Data Optimization — what creates unnecessary cost?

| Capability                    | What it does                                                                                                                                                                            |
| ----------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **True Query-Level Cost**     | Credits attributed to individual queries via `QUERY_ATTRIBUTION_HISTORY` — see [Reading Cost Numbers Correctly](#reading-cost-numbers-correctly) for what this does and doesn't include |
| **Query-Pattern Ranking**     | Groups queries by parameterized hash and ranks patterns by total cost, cost per execution, and frequency                                                                                |
| **Cost Regression Detection** | Week-over-week change per query pattern, so a query that quietly got 4× more expensive surfaces on its own                                                                              |
| **Pruning Efficiency**        | Partitions scanned vs. total, per table and per query pattern — usually the largest single lever                                                                                        |
| **Cache Effectiveness**       | Percentage scanned from cache, to find workloads re-reading the same data                                                                                                               |
| **Compilation Overhead**      | Flags patterns where compilation, not execution, dominates runtime                                                                                                                      |
| **Storage Optimization**      | Large low-activity tables, excessive Time Travel and Fail-safe overhead, rapid storage growth                                                                                           |
| **Service ROI Analysis**      | Automatic Clustering, Search Optimization, Materialized Views, and Query Acceleration — cost of the service against measured benefit                                                    |

### AI Cost Governance — which models, functions, and agents consume credits?

| Capability                               | What it does                                                                                       |
| ---------------------------------------- | -------------------------------------------------------------------------------------------------- |
| **Cortex Agent Cost**                    | Cost, requests, credits per request, and tokens per request, per agent                             |
| **Agent Tool Attribution**               | Traces an agent request down to the underlying Cortex Analyst and Cortex Search calls it triggered |
| **LLM & AI Function Cost**               | Input, output, and total tokens by model, function, user, role, warehouse, and query tag           |
| **Token Efficiency**                     | Tokens per request and cost per request, with anomaly and regression detection                     |
| **Cortex Search Cost**                   | Serving, embedding, and batch-query cost per search service                                        |
| **Cortex Analyst & Guardrails**          | Request volume and credit consumption, including guardrail scan cost                               |
| **Fine-Tuning & Provisioned Throughput** | Training-run cost and provisioned-throughput utilization                                           |
| **Unified AI View**                      | Snowflake AI spend next to OpenAI, Anthropic, Bedrock, and your other AI providers                 |

## Security at a Glance

| Question                                            | Answer                                                                                                                                                                                                                                                                                                                                           |
| --------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **Does OneLens read our production data?**          | No. Access is restricted to the built-in `SNOWFLAKE` database via Snowflake's own `ACCOUNT_USAGE` and `ORGANIZATION_USAGE` views. The role has zero privileges on any other database.                                                                                                                                                            |
| **What exactly is granted?**                        | Three Snowflake-managed database roles — `USAGE_VIEWER`, `GOVERNANCE_VIEWER`, and `OBJECT_VIEWER` — plus the three `ORGANIZATION_USAGE` roles. **`SECURITY_VIEWER` is deliberately not granted.**                                                                                                                                                |
| **What does excluding `SECURITY_VIEWER` protect?**  | Login history, user records, role grants, sessions, network policies, secrets, and credentials stay inaccessible. None of these have a cost-management purpose.                                                                                                                                                                                  |
| **Does the grant include more than OneLens reads?** | Yes, and it's worth knowing. `GOVERNANCE_VIEWER` is required for `QUERY_HISTORY`, and it also carries `ACCESS_HISTORY` (which columns a query touched). OneLens does not ingest `ACCESS_HISTORY`. Snowflake's role granularity does not allow separating the two — see [Secure-View Alternative](#appendix-secure-view-alternative).             |
| **Does OneLens see query text?**                    | **By default, yes** — we read `QUERY_TEXT` so we can show you the exact query to fix. If your queries carry sensitive content, ask your OneLens contact to enable **hash-only mode**: we ingest `QUERY_PARAMETERIZED_HASH` (plus `QUERY_PARAMETERIZED_HASH_VERSION`) instead. The hash is one-way, so literal values can never be reconstructed. |
| **Does query-level cost data expose query text?**   | No. `QUERY_ATTRIBUTION_HISTORY` has no `QUERY_TEXT` column at all — only IDs, hashes, tags, user, and credits. Cost Intelligence and the cost-ranking half of Query Optimization work unchanged in hash-only mode.                                                                                                                               |
| **Does OneLens see user identities?**               | Yes — `USER_NAME`, `ROLE_NAME`, and warehouse owner appear in usage views and are used for per-user and per-team attribution.                                                                                                                                                                                                                    |
| **Is access read-only?**                            | Yes. `ONELENS_ROLE` has no `INSERT` / `UPDATE` / `DELETE` / `CREATE` privileges. It can run only `SELECT` on metadata views.                                                                                                                                                                                                                     |
| **What authentication is used?**                    | RSA key-pair. Snowflake-signed JWTs only; no shared secrets in flight.                                                                                                                                                                                                                                                                           |
| **How is data transmitted and stored?**             | TLS 1.2+ in transit; encrypted at rest. Private keys and credentials are stored encrypted and never logged.                                                                                                                                                                                                                                      |
| **Can I restrict by IP?**                           | Yes — see the network policy step. OneLens egress IPs are `35.244.46.16/32`, `34.120.137.88/32`, `35.201.115.143/32`.                                                                                                                                                                                                                            |
| **Where does the data live?**                       | Contact OneLens for the current Trust & Security overview — region/cloud, retention policy, sub-processors, SOC 2 / ISO 27001 status, and DPA.                                                                                                                                                                                                   |

## Cost of the Integration

OneLens creates one XSMALL warehouse and nothing else. Querying `ACCOUNT_USAGE` is not itself billed — you pay only for the warehouse time spent running the queries.

Figures assume `ONELENS_WH` is XSMALL (**1 credit/hour**) with 60-second auto-suspend.

| Item                                             | Math                                                | Typical cost     |
| ------------------------------------------------ | --------------------------------------------------- | ---------------- |
| **Core cost & metering queries**                 | \~5 min/day → 2.5 credits/month                     | $5–10/month      |
| **Deep warehouse, query, storage, and AI views** | \~10–20 min/day → 5–10 credits/month                | $10–40/month     |
| **Storage in your account**                      | None — OneLens writes nothing back                  | $0               |
| **New warehouses or objects**                    | One XSMALL warehouse; no clusters, tasks, or tables | $0               |
| **Estimated total**                              | **7.5–12.5 credits/month** at $2–4/credit           | **$15–50/month** |

Where you land depends mostly on query volume. The two heaviest reads are `QUERY_HISTORY` and `TABLE_STORAGE_METRICS`; an account running millions of queries a day will sit at the upper end. Three things keep it bounded:

* Every OneLens query is time-bounded on the view's primary time column. Snowflake rejects unbounded scans of these views anyway, and unbounded scans are the main way tools like this get expensive.
* Closed months are read once and never re-queried.
* After the initial backfill, reads are incremental.

{% hint style="info" %}
**The initial backfill is the expensive day.** Backfilling 12 months across \~40 views is a one-time cost of roughly 5–15 additional credits. If your credit rate is high, ask OneLens to stage the backfill over several nights.
{% endhint %}

## How It Works

Snowflake charges for **compute** (credits consumed by virtual warehouses and serverless features), **storage** (per TB), and **data transfer**. Bills grow when warehouses are oversized or idle, when queries scan more data than they need, when serverless services run without anyone checking their return, and — increasingly — when AI features consume tokens nobody is tracking.

Snowflake exposes all of this through metadata views in the shared `SNOWFLAKE` database. OneLens reads five categories: usage and metering, contracted cost, query metadata and attribution, object and storage metadata, and AI service usage.

Everything OneLens reads is a view Snowflake maintains for you. OneLens creates no tables, materializes nothing inside your account, and writes nothing back.

## What OneLens Reads

All views are in `SNOWFLAKE.ACCOUNT_USAGE` unless marked otherwise. Latency is Snowflake's published maximum for that view.

### Cost Intelligence

| View                                         | Latency        | Notes                                                         |
| -------------------------------------------- | -------------- | ------------------------------------------------------------- |
| `WAREHOUSE_METERING_HISTORY`                 | 3 hours        | Credits per warehouse per hour                                |
| `METERING_HISTORY`                           | 3 hours        | Cloud-services credits up to 6h; Snowpipe Streaming up to 12h |
| `METERING_DAILY_HISTORY`                     | 3 hours        | Daily rollup including the cloud-services adjustment          |
| `ORGANIZATION_USAGE.USAGE_IN_CURRENCY_DAILY` | up to 72 hours | Dollar cost at your contract rate                             |
| `ORGANIZATION_USAGE.RATE_SHEET_DAILY`        | up to 72 hours | Your per-credit and per-TB rates                              |
| `DATA_TRANSFER_HISTORY`                      | 2 hours        | Egress and cross-region transfer                              |
| `ANOMALIES_DAILY`                            | 3 hours        | Snowflake's own anomaly signals, used to corroborate ours     |

### Warehouse Optimization

| View                       | Latency    | Notes                                                           |
| -------------------------- | ---------- | --------------------------------------------------------------- |
| `WAREHOUSE_LOAD_HISTORY`   | 3 hours    | Running, queued-overload, queued-provisioning, and blocked load |
| `WAREHOUSE_EVENTS_HISTORY` | 3 hours    | Resize, suspend, resume events                                  |
| `QUERY_HISTORY`            | 45 minutes | Queue times, spill bytes, compilation time, partitions scanned  |

Warehouse *configuration* (size, auto-suspend, min/max clusters, scaling policy) has no `ACCOUNT_USAGE` view. It comes from `MONITOR USAGE ON ACCOUNT` plus `MONITOR ON WAREHOUSE`, which is why the setup script grants both.

### Query & Data Optimization

| View                             | Latency     | Notes                                                          |
| -------------------------------- | ----------- | -------------------------------------------------------------- |
| `QUERY_ATTRIBUTION_HISTORY`      | **8 hours** | Credits per query; no query text. Excludes Adaptive Warehouses |
| `QUERY_METERING_HISTORY`         | 1 hour      | Per-query credits for Adaptive Warehouses                      |
| `QUERY_INSIGHTS`                 | —           | Snowflake's own detected query problems                        |
| `TABLE_STORAGE_METRICS`          | 90 minutes  | Active, Time Travel, Fail-safe, and retained bytes per table   |
| `DATABASE_STORAGE_USAGE_HISTORY` | 3 hours     | Storage growth per database                                    |
| `STAGE_STORAGE_USAGE_HISTORY`    | 2 hours     | Internal stage storage                                         |
| `TABLE_DML_HISTORY`              | 6 hours     | Write activity, to find high-storage/low-activity tables       |
| `TABLE_PRUNING_HISTORY`          | 6 hours     | Pruning efficiency per table                                   |
| `TABLE_QUERY_PRUNING_HISTORY`    | 4 hours     | Pruning efficiency per table per query                         |
| `COLUMN_QUERY_PRUNING_HISTORY`   | 4 hours     | Column-level pruning                                           |
| `QUERY_ACCELERATION_ELIGIBLE`    | 3 hours     | Queries that would benefit from QAS — the ROI input            |

### Serverless & Service Costs

| View                                | Latency    | Edition         |
| ----------------------------------- | ---------- | --------------- |
| `SERVERLESS_TASK_HISTORY`           | 3 hours    | All             |
| `TASK_HISTORY`                      | 45 minutes | All             |
| `PIPE_USAGE_HISTORY`                | 3 hours    | All             |
| `SNOWPIPE_STREAMING_CLIENT_HISTORY` | 2 hours    | All             |
| `AUTOMATIC_CLUSTERING_HISTORY`      | 3 hours    | All             |
| `DYNAMIC_TABLE_REFRESH_HISTORY`     | 3 hours    | All             |
| `MATERIALIZED_VIEW_REFRESH_HISTORY` | 3 hours    | **Enterprise+** |
| `SEARCH_OPTIMIZATION_HISTORY`       | 3 hours    | **Enterprise+** |
| `SEARCH_OPTIMIZATION_BENEFITS`      | 6 hours    | **Enterprise+** |
| `QUERY_ACCELERATION_HISTORY`        | 3 hours    | **Enterprise+** |

{% hint style="warning" %}
**Edition matters for ROI analysis.** Materialized View, Search Optimization, and Query Acceleration cost-vs-benefit analysis requires Enterprise Edition or higher. On Standard Edition those views do not exist, and OneLens shows the sections as unavailable rather than empty. Everything in Cost Intelligence and Warehouse Optimization works on Standard.
{% endhint %}

### AI Cost Governance

| View                                          | Latency | Covers                                                    |
| --------------------------------------------- | ------- | --------------------------------------------------------- |
| `CORTEX_AGENT_USAGE_HISTORY`                  | 1 hour  | Agent requests, credits, tokens, tool-level detail        |
| `SNOWFLAKE_INTELLIGENCE_USAGE_HISTORY`        | 1 hour  | Snowflake CoWork interactions — **not** in the agent view |
| `CORTEX_AI_FUNCTIONS_USAGE_HISTORY`           | —       | AI function token and credit usage                        |
| `CORTEX_AISQL_USAGE_HISTORY`                  | —       | AI functions used inside SQL queries                      |
| `CORTEX_FUNCTIONS_USAGE_HISTORY`              | —       | Legacy Cortex function usage                              |
| `CORTEX_FUNCTIONS_QUERY_USAGE_HISTORY`        | —       | Legacy per-query Cortex function usage                    |
| `CORTEX_SEARCH_SERVING_USAGE_HISTORY`         | 1 hour  | Search serving cost                                       |
| `CORTEX_SEARCH_DAILY_USAGE_HISTORY`           | 3 hours | Daily search + embedding cost                             |
| `CORTEX_SEARCH_BATCH_QUERY_USAGE_HISTORY`     | 1 hour  | Batch query cost                                          |
| `CORTEX_ANALYST_USAGE_HISTORY`                | 1 hour  | Analyst request volume and credits                        |
| `CORTEX_AI_GUARDRAILS_USAGE_HISTORY`          | —       | Guardrail scans, flags, credits, tokens                   |
| `CORTEX_DOCUMENT_PROCESSING_USAGE_HISTORY`    | 1 hour  | Document AI processing                                    |
| `CORTEX_FINE_TUNING_USAGE_HISTORY`            | 1 hour  | Fine-tuning run cost                                      |
| `CORTEX_PROVISIONED_THROUGHPUT_USAGE_HISTORY` | —       | Provisioned throughput utilization                        |
| `CORTEX_REST_API_USAGE_HISTORY`               | —       | Cortex REST API consumption                               |

{% hint style="warning" %}
**Agent cost needs two views, not one.** `CORTEX_AGENT_USAGE_HISTORY` explicitly excludes requests that originate from Snowflake CoWork; those land in `SNOWFLAKE_INTELLIGENCE_USAGE_HISTORY`. Reading only the first understates agent spend. OneLens reads both and reconciles them without double-counting. Snowflake also lists a `SNOWFLAKE_COWORK_USAGE_HISTORY` view — the naming is in transition, so OneLens probes for both and uses whichever is present in your account.
{% endhint %}

### What OneLens Will NOT Access

* Your actual data, tables, or rows in any database other than `SNOWFLAKE`
* `SECURITY_VIEWER` scope — no login history, user records, role grants, sessions, secrets, or credentials
* `ACCESS_HISTORY` — never ingested, even though `GOVERNANCE_VIEWER` technically permits it
* Any write access — read-only by design

## Reading Cost Numbers Correctly

This section exists because the most common question on a Snowflake FinOps rollout is *"why don't your per-query costs add up to my bill?"* They will not, and that is correct behaviour.

**Query-attributed credits are always less than warehouse credits.** `CREDITS_ATTRIBUTED_COMPUTE` covers only credits burned executing the query. Snowflake explicitly excludes warehouse idle time, cloud services credits, storage and data transfer costs, serverless feature costs, and tokens processed by AI services.

OneLens shows the gap as an explicit **idle and overhead** line rather than silently spreading it across queries. If that line is large, it is itself the finding: you are paying for a warehouse to sit awake.

**Some queries are missing by design.** Queries at or under roughly 100 ms are too short to attribute and do not appear at all. On a high-frequency workload this is a visible number of rows, though a small share of credits.

**Adaptive Warehouses use a different view.** Jobs on Adaptive Warehouses do not appear in `QUERY_ATTRIBUTION_HISTORY`; their per-query credits come from `QUERY_METERING_HISTORY`. OneLens reads both and labels which source a figure came from.

**Attribution starts mid-August 2024.** Data before that may be incomplete regardless of your backfill window.

**Concurrent queries are apportioned, not measured.** When queries run at the same time, warehouse cost is split by weighted average resource consumption. An individual query's cost is a fair estimate, not a meter reading — trust the pattern-level rollups more than any single row.

**Accelerated queries have two cost columns.** For a query accelerated by QAS, true cost is `CREDITS_ATTRIBUTED_COMPUTE` **plus** `CREDITS_USED_QUERY_ACCELERATION`. OneLens sums both.

**Contract cost and credits reconcile only in UTC.** `ACCOUNT_USAGE` and `ORGANIZATION_USAGE` will not tie out unless the session timezone is UTC. OneLens sets this on every connection; if you reconcile by hand, run `ALTER SESSION SET TIMEZONE = UTC;` first.

## Prerequisites

* **Snowflake Edition**: Standard, Enterprise, Business Critical, or VPS. Free trial accounts are not supported for production integration. Service ROI analysis requires Enterprise or higher.
* A user with the **`ACCOUNTADMIN`** role to run the setup script.
* **`ORGADMIN` enabled on at least one account in your Snowflake org.** This is a one-time, org-wide prerequisite that makes `ORGANIZATION_USAGE` views populate. You do **not** need `ORGADMIN` to run the setup script — only to flip the enablement switch in Snowsight (**Admin → Accounts**) on the org's primary account, if not already enabled.
* A machine with `openssl` installed, to generate the key pair.

{% stepper %}
{% step %}

## Identify Your Snowflake Account Identifier

1. Log into Snowsight (Snowflake's web UI).
2. In the bottom-left corner, click your username → **Connect a tool to Snowflake**.
3. Copy the **Account Identifier**. It looks like one of:
   * `myorg-myaccount` (preferred format: `<org_name>-<account_name>`)
   * `abc12345.us-east-1` (legacy format: `<account_locator>.<region>`)

You'll also need your **server URL**, which is just `<account_identifier>.snowflakecomputing.com`.
{% endstep %}

{% step %}

## Generate a Key Pair

OneLens uses key-pair authentication. Snowflake is in the middle of a phased rollout that retires password authentication for users and enforces MFA — key-pair is the recommended secure pattern for any automated integration and avoids being swept up in that deprecation.

```bash
# Private key (give this to OneLens in the final step — never commit to git)
openssl genrsa 2048 | openssl pkcs8 -topk8 -inform PEM \
  -out onelens_rsa_key.p8 -nocrypt

# Matching public key (paste this into the SQL script in the next step)
openssl rsa -in onelens_rsa_key.p8 -pubout -out onelens_rsa_key.pub
```

Open `onelens_rsa_key.pub` and copy the key body — everything **between** `-----BEGIN PUBLIC KEY-----` and `-----END PUBLIC KEY-----`, with line breaks removed.

{% hint style="info" %}
If your security policy requires it, use an encrypted private key (`pkcs8` without `-nocrypt`) and a passphrase. Share the passphrase with OneLens alongside the private key.
{% endhint %}
{% endstep %}

{% step %}

## Run the OneLens Setup Script

This creates a dedicated read-only role, user, and warehouse, attaches your public key, and applies the grants. Run it as `ACCOUNTADMIN` in a Snowflake worksheet.

Paste your public key body where the script says `<PASTE_PUBLIC_KEY_BODY_HERE>`.

```sql
-- =========================================================
-- OneLens Snowflake Integration Setup
-- Run this as ACCOUNTADMIN
-- =========================================================

USE ROLE ACCOUNTADMIN;

-- 1. Dedicated warehouse for OneLens
--    XSMALL = 1 credit/hr; AUTO_SUSPEND = 60s keeps idle cost near zero.
--    (Snowflake's default AUTO_SUSPEND is 600s; we override to 60.)
CREATE WAREHOUSE IF NOT EXISTS ONELENS_WH
  WAREHOUSE_SIZE = 'XSMALL'
  AUTO_SUSPEND = 60
  AUTO_RESUME = TRUE
  INITIALLY_SUSPENDED = TRUE
  COMMENT = 'Warehouse used by OneLens for read-only cost/usage queries';

-- 2. Dedicated role and service user
CREATE ROLE IF NOT EXISTS ONELENS_ROLE
  COMMENT = 'Read-only role for OneLens cost & usage integration';

CREATE USER IF NOT EXISTS ONELENS_USER
  TYPE = SERVICE
  RSA_PUBLIC_KEY = '<PASTE_PUBLIC_KEY_BODY_HERE>'
  DEFAULT_ROLE = ONELENS_ROLE
  DEFAULT_WAREHOUSE = ONELENS_WH
  COMMENT = 'Service user for OneLens cost & usage integration';

GRANT ROLE ONELENS_ROLE TO USER ONELENS_USER;
GRANT ROLE ONELENS_ROLE TO ROLE ACCOUNTADMIN;

-- 3. Warehouse usage
GRANT USAGE, OPERATE ON WAREHOUSE ONELENS_WH TO ROLE ONELENS_ROLE;

-- 4. ACCOUNT_USAGE access via named database roles.
--    This replaces GRANT IMPORTED PRIVILEGES ON DATABASE SNOWFLAKE.
--    Snowflake recommends database roles so you don't over-grant.
--
--    USAGE_VIEWER      -> metering, storage, serverless, Cortex/AI usage,
--                         warehouse load, query attribution, pruning
--    GOVERNANCE_VIEWER -> QUERY_HISTORY, QUERY_INSIGHTS, TAG_REFERENCES,
--                         QUERY_ACCELERATION_ELIGIBLE
--    OBJECT_VIEWER     -> TABLES, DATABASES, SCHEMATA, TAGS, PIPES, TASKS
--
--    SECURITY_VIEWER is intentionally NOT granted. That excludes
--    LOGIN_HISTORY, USERS, GRANTS_TO_*, SESSIONS, SECRETS, CREDENTIALS.
GRANT DATABASE ROLE SNOWFLAKE.USAGE_VIEWER      TO ROLE ONELENS_ROLE;
GRANT DATABASE ROLE SNOWFLAKE.GOVERNANCE_VIEWER TO ROLE ONELENS_ROLE;
GRANT DATABASE ROLE SNOWFLAKE.OBJECT_VIEWER     TO ROLE ONELENS_ROLE;

-- 5. Account-wide usage visibility + warehouse configuration metadata.
--    Warehouse size / auto-suspend / cluster settings have no
--    ACCOUNT_USAGE view, so these grants are how right-sizing works.
GRANT MONITOR USAGE ON ACCOUNT TO ROLE ONELENS_ROLE;
GRANT MONITOR ON WAREHOUSE ONELENS_WH TO ROLE ONELENS_ROLE;

-- 6. ORGANIZATION_USAGE access for contracted dollar costs.
--    ACCOUNTADMIN can grant these directly; ORGADMIN is NOT required
--    for the GRANTs — only (once) to enable ORGANIZATION_USAGE for the
--    account, in Snowsight under Admin -> Accounts.
GRANT DATABASE ROLE SNOWFLAKE.ORGANIZATION_USAGE_VIEWER    TO ROLE ONELENS_ROLE;
GRANT DATABASE ROLE SNOWFLAKE.ORGANIZATION_BILLING_VIEWER  TO ROLE ONELENS_ROLE;
GRANT DATABASE ROLE SNOWFLAKE.ORGANIZATION_ACCOUNTS_VIEWER TO ROLE ONELENS_ROLE;
```

You should see "Statement executed successfully" for each command.

{% hint style="info" %}
**About the `ORGANIZATION_USAGE` grants:** these views contain the dollar values of your Snowflake spend (credits × your contract rate), exposed through three Snowflake-managed database roles — `ORGANIZATION_USAGE_VIEWER` (compute/storage usage), `ORGANIZATION_BILLING_VIEWER` (billing & currency), and `ORGANIZATION_ACCOUNTS_VIEWER` (account list). `ACCOUNTADMIN` can grant all three.
{% endhint %}
{% endstep %}

{% step %}

## Verify the Setup

`ONELENS_USER` is a `TYPE = SERVICE` user, which means **it cannot log into Snowsight**. Verify as `ACCOUNTADMIN` impersonating the role, or via SnowSQL with the private key.

Note the explicit column lists — Snowflake advises against `SELECT *` on these views because columns are added over time.

```sql
USE ROLE ONELENS_ROLE;
USE WAREHOUSE ONELENS_WH;
ALTER SESSION SET TIMEZONE = UTC;

-- 1. Core metering (Cost Intelligence)
SELECT warehouse_name, SUM(credits_used) AS credits
FROM SNOWFLAKE.ACCOUNT_USAGE.WAREHOUSE_METERING_HISTORY
WHERE start_time >= DATEADD('day', -7, CURRENT_TIMESTAMP())
GROUP BY 1 LIMIT 5;

-- 2. Contracted cost (needs ORGANIZATION_USAGE enabled)
SELECT usage_date, usage_type, currency, SUM(usage_in_currency) AS spend
FROM SNOWFLAKE.ORGANIZATION_USAGE.USAGE_IN_CURRENCY_DAILY
WHERE usage_date >= DATEADD('day', -7, CURRENT_DATE())
GROUP BY 1,2,3 LIMIT 5;

-- 3. Warehouse load (Warehouse Optimization)
SELECT warehouse_name, AVG(avg_running) AS running,
       AVG(avg_queued_load) AS queued
FROM SNOWFLAKE.ACCOUNT_USAGE.WAREHOUSE_LOAD_HISTORY
WHERE start_time >= DATEADD('day', -7, CURRENT_TIMESTAMP())
GROUP BY 1 LIMIT 5;

-- 4. Query-level cost (Query Optimization) — allow 8h latency
SELECT query_parameterized_hash,
       COUNT(*) AS execs,
       SUM(credits_attributed_compute) AS credits
FROM SNOWFLAKE.ACCOUNT_USAGE.QUERY_ATTRIBUTION_HISTORY
WHERE start_time >= DATEADD('day', -7, CURRENT_TIMESTAMP())
GROUP BY 1 ORDER BY credits DESC LIMIT 5;

-- 5. Storage detail (Data Optimization)
SELECT table_catalog, SUM(active_bytes) AS active,
       SUM(time_travel_bytes) AS time_travel
FROM SNOWFLAKE.ACCOUNT_USAGE.TABLE_STORAGE_METRICS
WHERE deleted = FALSE
GROUP BY 1 LIMIT 5;

-- 6. AI cost (AI Cost Governance) — empty is fine if Cortex is unused
SELECT model_name, SUM(credits) AS credits
FROM SNOWFLAKE.ACCOUNT_USAGE.CORTEX_AI_FUNCTIONS_USAGE_HISTORY
WHERE start_time >= DATEADD('day', -30, CURRENT_TIMESTAMP())
GROUP BY 1 LIMIT 5;
```

How to read the results:

* **Queries 1, 3, and 5 return rows** → the core integration is working.
* **Query 2 returns nothing** → `ORGANIZATION_USAGE` is not enabled, or you bought through a reseller. See troubleshooting items 1 and 9.
* **Query 4 returns nothing** → most likely the 8-hour latency, or an account on Adaptive Warehouses. Re-run tomorrow before escalating.
* **Query 6 returns nothing** → expected if you don't use Cortex AI functions. Not an error.
* **Any query fails with "object does not exist or not authorized"** → note *which* view, and check its Edition requirement before assuming a grant problem.
  {% endstep %}

{% step %}

## Connect to OneLens

In OneLens, open **Settings → Connections → Snowflake** and provide:

| Field                                          | Value                                                                                   |
| ---------------------------------------------- | --------------------------------------------------------------------------------------- |
| Account Identifier                             | From step 1 (e.g., `myorg-myaccount`)                                                   |
| Server URL                                     | `<account_identifier>.snowflakecomputing.com`                                           |
| Username                                       | `ONELENS_USER`                                                                          |
| Role                                           | `ONELENS_ROLE`                                                                          |
| Warehouse                                      | `ONELENS_WH`                                                                            |
| Database                                       | `SNOWFLAKE`                                                                             |
| Private Key                                    | Full contents of `onelens_rsa_key.p8`, including headers and line breaks                |
| Passphrase *(only if encrypted)*               | The passphrase from step 2                                                              |
| Per-credit rate *(only if reseller-purchased)* | Your $/credit and $/TB rates if `USAGE_IN_CURRENCY_DAILY` is empty                      |
| Snowflake Edition                              | Standard / Enterprise / Business Critical / VPS — determines which ROI modules activate |
| Hash-only mode *(optional)*                    | Request here if raw query text must not leave your account                              |

{% hint style="info" %}
**Multiple accounts:** connect each Snowflake account separately so OneLens can pull `ACCOUNT_USAGE` from each. Cost rollups via `ORGANIZATION_USAGE` work automatically once the parent account is connected.
{% endhint %}
{% endstep %}
{% endstepper %}

## Optional: Cost Attribution by Query Tag

Snowflake's Query Tags let you attribute costs to teams, services, or environments. `QUERY_TAG` appears in both `QUERY_HISTORY` and `QUERY_ATTRIBUTION_HISTORY`, so tagging gives you tag-level **dollar** cost, not just tag-level query counts. OneLens parses JSON tags into key/value pairs automatically:

```sql
-- Plain string tag
ALTER SESSION SET QUERY_TAG = 'team=growth';

-- Or JSON for structured tagging
ALTER SESSION SET QUERY_TAG = '{"team":"growth","service":"checkout","env":"prod"}';
```

This is the highest-leverage optional step on this page. Without tags, cost allocation stops at warehouse and user. With tags, it reaches teams and services.

## Data Refresh Schedule

OneLens pulls Snowflake usage, cost, and query metadata **once per day**. Snowflake's own view latency is the binding constraint, not our schedule:

* `QUERY_HISTORY` up to 45 minutes
* Most metering and load views up to 3 hours
* `METERING_HISTORY` cloud-services credits up to 6 hours; Snowpipe Streaming up to 12 hours
* **`QUERY_ATTRIBUTION_HISTORY` up to 8 hours** — the longest of any view OneLens reads, and the reason query-level cost lags query metadata by roughly a day
* `USAGE_IN_CURRENCY_DAILY` up to 72 hours, and **not finalized until the month closes**

Polling more often would not surface fresher data, and would multiply warehouse cost.

Closed months are static once Snowflake finalizes them — pulled once and not re-queried. Current-month figures may shift until the month closes. Query-level cost for the last 24 hours may be incomplete because of the 8-hour attribution latency; treat yesterday's per-query numbers as provisional.

If you need faster refreshes for a specific use case — intra-day anomaly detection, or watching an agent rollout — contact OneLens support. Cortex views have 1-hour latency and can support a faster cadence for AI cost specifically.

## Data Privacy & Security

* **Read-only access** — `ONELENS_ROLE` has no `INSERT`/`UPDATE`/`DELETE`/`CREATE` on your data.
* **Metadata only** — access is limited to the `SNOWFLAKE` system database; your production data, tables, and rows are never read.
* **Named database roles, not blanket privileges** — three specific roles instead of `IMPORTED PRIVILEGES`.
* **No `SECURITY_VIEWER`** — login history, user records, role grants, sessions, secrets, and credentials remain inaccessible.
* **No `ACCESS_HISTORY` ingestion**, even though `GOVERNANCE_VIEWER` permits it.
* **Encrypted credentials** — at rest and in transit; private keys are never logged.
* **No mutation** — OneLens cannot modify warehouse settings, drop objects, or run any non-`SELECT` statement.
* **Network restriction supported** — pin access to OneLens egress IPs.
* **Hash-only mode available** if raw query text must never leave your account.

## Troubleshooting

<details>

<summary>1. <code>Object does not exist or not authorized</code> querying <code>ORGANIZATION_USAGE.*</code></summary>

**Cause:** Either `ORGANIZATION_USAGE` isn't enabled for your account at the org level, or the database-role grants didn't apply.

**Fix:** Re-apply the grants:

```sql
USE ROLE ACCOUNTADMIN;
GRANT DATABASE ROLE SNOWFLAKE.ORGANIZATION_USAGE_VIEWER    TO ROLE ONELENS_ROLE;
GRANT DATABASE ROLE SNOWFLAKE.ORGANIZATION_BILLING_VIEWER  TO ROLE ONELENS_ROLE;
GRANT DATABASE ROLE SNOWFLAKE.ORGANIZATION_ACCOUNTS_VIEWER TO ROLE ONELENS_ROLE;
```

If the grants succeed but queries still fail, `ORGANIZATION_USAGE` is not enabled. Log into Snowsight on the account holding `ORGADMIN` (usually the original account Snowflake provisioned), switch to `ORGADMIN`, go to **Admin → Accounts**, and confirm it's enabled. Data populates within \~24 hours.

To check whether your user even sees the role: `SHOW ROLES LIKE 'ORGADMIN';` — this lists only roles your hierarchy can see, so an empty result means you lack access to it, not that it doesn't exist.

</details>

<details>

<summary>2. <code>Object does not exist or not authorized</code> on a specific <code>ACCOUNT_USAGE</code> view</summary>

**Cause:** Three possibilities, in order of likelihood. (a) The view requires **Enterprise Edition or higher** and you're on Standard — this applies to `MATERIALIZED_VIEW_REFRESH_HISTORY`, `SEARCH_OPTIMIZATION_HISTORY`, `SEARCH_OPTIMIZATION_BENEFITS`, and `QUERY_ACCELERATION_HISTORY`. (b) The required database role wasn't granted. (c) The view is newer than your account's release track.

**Fix:** Check your grants:

```sql
USE ROLE ACCOUNTADMIN;
SHOW GRANTS TO ROLE ONELENS_ROLE;
-- Expect USAGE_VIEWER, GOVERNANCE_VIEWER, OBJECT_VIEWER and the
-- three ORGANIZATION_* roles in the output.
```

If the role is granted and your Edition is sufficient, tell OneLens which view failed — we'll disable that module rather than let it retry.

</details>

<details>

<summary>3. <code>JWT_TOKEN_INVALID_PUBLIC_KEY_FINGERPRINT_MISMATCH</code> or <code>Invalid username or password</code></summary>

**Cause:** Snowflake returns this generic error for several key-pair failures. Most common: the public key in Snowflake doesn't match the private key OneLens has, or the public key includes the `-----BEGIN/END PUBLIC KEY-----` headers when it shouldn't.

**Fix:** Re-paste the key body **only** — no headers, no newlines:

```sql
USE ROLE ACCOUNTADMIN;
ALTER USER ONELENS_USER SET RSA_PUBLIC_KEY = '<KEY_BODY_ONLY_NO_HEADERS>';

-- Verify it took
DESC USER ONELENS_USER;
-- Check the RSA_PUBLIC_KEY_FP (fingerprint) row and confirm with
-- OneLens that it matches the private key they hold.
```

</details>

<details>

<summary>4. Query-level costs don't sum to the warehouse total</summary>

**Cause:** Expected behaviour, not a bug. `CREDITS_ATTRIBUTED_COMPUTE` excludes idle time, cloud services, storage, transfer, serverless, and AI token costs. See [Reading Cost Numbers Correctly](#reading-cost-numbers-correctly).

**Fix:** No action needed. To compare the two figures deliberately:

```sql
ALTER SESSION SET TIMEZONE = UTC;

SELECT
  (SELECT SUM(credits_used_compute)
     FROM SNOWFLAKE.ACCOUNT_USAGE.WAREHOUSE_METERING_HISTORY
    WHERE start_time >= DATEADD('day', -7, CURRENT_TIMESTAMP())
  ) AS warehouse_credits,
  (SELECT SUM(credits_attributed_compute)
     FROM SNOWFLAKE.ACCOUNT_USAGE.QUERY_ATTRIBUTION_HISTORY
    WHERE start_time >= DATEADD('day', -7, CURRENT_TIMESTAMP())
  ) AS attributed_credits;
```

The difference is predominantly idle time. If it exceeds \~30%, that is itself a finding worth acting on.

</details>

<details>

<summary>5. <code>ACCOUNT_USAGE</code> and <code>ORGANIZATION_USAGE</code> totals disagree</summary>

**Cause:** Session timezone. Snowflake requires UTC to reconcile these schemas.

**Fix:** Run `ALTER SESSION SET TIMEZONE = UTC;` before comparing. OneLens does this automatically.

</details>

<details>

<summary>6. <code>View definition for 'X' declared N column(s), but view query produces M column(s)</code></summary>

**Cause:** Snowflake adds columns to `ACCOUNT_USAGE` views over time. Tools that materialize their own copies drift.

**Fix:** This is on the OneLens side — open a ticket and we'll refresh our view definitions and re-import. No customer action needed.

</details>

<details>

<summary>7. <code>ONELENS_WH does not exist or not authorized</code></summary>

**Cause:** The warehouse wasn't created, or `USAGE`/`OPERATE` wasn't granted.

**Fix:**

```sql
USE ROLE ACCOUNTADMIN;
SHOW WAREHOUSES LIKE 'ONELENS_WH';
-- If empty, re-run section 1 of the setup script.

GRANT USAGE, OPERATE ON WAREHOUSE ONELENS_WH TO ROLE ONELENS_ROLE;
```

</details>

<details>

<summary>8. <code>IP &#x3C;x.x.x.x> is not allowed to access Snowflake</code></summary>

**Cause:** An account-wide or user-level network policy is blocking OneLens egress IPs.

**Fix:** Add the three IPs to your existing policy. To check what policy is in effect:

```sql
SHOW PARAMETERS LIKE 'NETWORK_POLICY' IN ACCOUNT;
SHOW PARAMETERS LIKE 'NETWORK_POLICY' IN USER ONELENS_USER;
```

</details>

<details>

<summary>9. Reseller account — no <code>ORGANIZATION_USAGE.USAGE_IN_CURRENCY_DAILY</code></summary>

**Cause:** If your capacity was sold by a **Snowflake reseller partner** rather than Snowflake directly, `USAGE_IN_CURRENCY_DAILY` and `RATE_SHEET_DAILY` will not populate — Snowflake doesn't hold your billing contract, so it doesn't know your $/credit rate. Buying through a **cloud marketplace** (AWS / Azure / GCP) is *not* the same as a reseller; those contracts are direct with Snowflake and the views populate normally.

**Fix:** The grants still succeed and are harmless. Provide OneLens with your per-credit and per-TB rates manually in the connection form. OneLens computes dollar cost from `WAREHOUSE_METERING_HISTORY` × your rate. Note this is exact for compute but approximate for serverless features with their own SKU rates.

</details>

<details>

<summary>10. AI cost sections are empty but we use Cortex</summary>

**Cause:** Most likely the wrong view for your workload. Agent requests from **Snowflake CoWork** do not appear in `CORTEX_AGENT_USAGE_HISTORY` — they're recorded in `SNOWFLAKE_INTELLIGENCE_USAGE_HISTORY`. AI functions called inside SQL may land in `CORTEX_AISQL_USAGE_HISTORY` rather than `CORTEX_AI_FUNCTIONS_USAGE_HISTORY`.

**Fix:** Confirm which surface your teams actually use, then query both views directly. If one is populated and OneLens shows nothing, open a ticket with the view name.

</details>

<details>

<summary>11. <code>ONELENS_USER</code> was working, now auth fails</summary>

**Cause:** Snowflake's MFA-for-password-users rollout. If you originally used password auth, you may have been swept up in the deprecation.

**Fix:** Migrate to key-pair (steps 2–3). If you can't immediately, the short-term workaround is setting the user's `TYPE` to `LEGACY_SERVICE` to opt out of MFA enforcement — Snowflake has flagged `LEGACY_SERVICE` as transitional, so plan a real key-pair migration before the final cutover.

```sql
USE ROLE ACCOUNTADMIN;
ALTER USER ONELENS_USER SET TYPE = 'LEGACY_SERVICE';
```

</details>

<details>

<summary>12. Connection works, but no data after 24 hours</summary>

**Causes**, most to least common:

1. **View latency** — `QUERY_HISTORY` \~45 min, most metering 3h, `QUERY_ATTRIBUTION_HISTORY` **8h**, `USAGE_IN_CURRENCY_DAILY` up to 72h.
2. **`USAGE_IN_CURRENCY_DAILY` not yet populated** — newly enabled `ORGANIZATION_USAGE` takes up to 24 hours to backfill.
3. **`ONELENS_WH` suspended, resume slow** — cold start is 5–10s, which OneLens handles, but firewall/proxy issues can stretch it.
4. **Time-zone confusion** — `ACCOUNT_USAGE` timestamps are UTC; your UI may show local time.

**Fix:** Run the verification queries *as* `ONELENS_USER`. If they return rows, the problem is on the OneLens ingest side — open a ticket.

</details>

## Appendix: Migrating from the Previous Grant Model

If you onboarded with the earlier script, you have `GRANT IMPORTED PRIVILEGES ON DATABASE SNOWFLAKE`, which already covers every view on this page — **the integration keeps working with no changes**. You only need to act if you want the tighter grant.

```sql
USE ROLE ACCOUNTADMIN;

-- Add the named roles first
GRANT DATABASE ROLE SNOWFLAKE.USAGE_VIEWER      TO ROLE ONELENS_ROLE;
GRANT DATABASE ROLE SNOWFLAKE.GOVERNANCE_VIEWER TO ROLE ONELENS_ROLE;
GRANT DATABASE ROLE SNOWFLAKE.OBJECT_VIEWER     TO ROLE ONELENS_ROLE;

-- Confirm OneLens ingest is healthy for a full cycle (24h), THEN revoke
REVOKE IMPORTED PRIVILEGES ON DATABASE SNOWFLAKE FROM ROLE ONELENS_ROLE;
```

{% hint style="warning" %}
Do not revoke before confirming a healthy 24-hour cycle. Revoking first will break ingest until the new grants propagate.
{% endhint %}

## Appendix: Secure-View Alternative

If your security team objects to `GOVERNANCE_VIEWER` because it technically exposes `ACCESS_HISTORY`, there is a stricter pattern: create your own views in your own database that select only the columns OneLens needs, and grant `ONELENS_ROLE` access to those views alone. `ONELENS_ROLE` then receives no database roles on `SNOWFLAKE` at all.

The trade-off is real: you own roughly 40 view definitions and must update them as Snowflake adds columns or as OneLens adds capabilities — which is exactly the drift described in troubleshooting item 6, except now on your side. Most customers accept the database-role grant instead. If you want this pattern, contact OneLens and we'll supply the DDL for the current view set.

## Appendix: Password Authentication (Not Recommended)

Key-pair is the default and supported path. If you cannot use key-pair — typically only for short-lived testing:

* Snowflake is phasing out password auth for service users on a rolling timeline.
* The user must be created as `TYPE = LEGACY_SERVICE` (not `SERVICE`) to bypass MFA enforcement.
* Provided for completeness only; we strongly recommend against it for production.

```sql
CREATE USER IF NOT EXISTS ONELENS_USER
  TYPE = LEGACY_SERVICE
  PASSWORD = '<INSERT_STRONG_RANDOM_PASSWORD>'
  DEFAULT_ROLE = ONELENS_ROLE
  DEFAULT_WAREHOUSE = ONELENS_WH
  MUST_CHANGE_PASSWORD = FALSE
  COMMENT = 'Service user for OneLens — password auth (legacy)';
```

Then share the **password** with OneLens instead of the private key.

## Frequently Asked Questions

<details>

<summary>Can OneLens see our actual data — tables, rows, or query results?</summary>

No. `ONELENS_ROLE` holds database roles on the built-in `SNOWFLAKE` database only, which exposes metadata views. It has no privileges on any other database, so it cannot list, browse, or query a single business table.

</details>

<details>

<summary>Why did the grant model change?</summary>

`GRANT IMPORTED PRIVILEGES ON DATABASE SNOWFLAKE` grants access to every `ACCOUNT_USAGE` view, including security views OneLens has no use for — login history, user records, role grants, secrets. Snowflake's own documentation recommends database roles instead, specifically to avoid over-granting. The current script grants the three roles that cover cost and usage, and omits `SECURITY_VIEWER`.

</details>

<details>

<summary>Can OneLens modify anything or run expensive queries?</summary>

No. The role has no `CREATE`, `WRITE`, or `MODIFY` privileges, and all OneLens queries are time-bounded read-only `SELECT`s on an XSMALL warehouse with 60-second auto-suspend.

</details>

<details>

<summary>How much will the OneLens warehouse cost us?</summary>

$15–50/month for most accounts — see [Cost of the Integration](#cost-of-the-integration) for the math. High-query-volume accounts trend to the upper end, and the initial 12-month backfill adds a one-time 5–15 credits.

</details>

<details>

<summary>Will OneLens see our actual query text?</summary>

By default yes — `QUERY_HISTORY.QUERY_TEXT` includes the SQL that ran, and OneLens reads it so we can show you the exact query to fix. Ask your OneLens contact to enable **hash-only mode** to ingest `QUERY_PARAMETERIZED_HASH` instead. Three precision points:

* **Privacy is one-way.** A hash cannot be reversed into SQL, so no literal values ever land in OneLens, regardless of where in the query the literal appears.
* **Grouping is partial.** Snowflake parameterizes only literals used with predicate comparison operators (`=`, `!=`, `>=`, `<=`). Two queries differing only in such a literal group together. Queries differing in `LIKE` patterns, `IN(...)` lists, projection literals, or function arguments produce different hashes and won't group.
* **Drill-down is gone.** You'll see "this query pattern cost $12k last month" but not the exact SQL — only your team can map a hash back to a query.

Snowflake truncates `QUERY_TEXT` at 1 MB before persisting, so even default-mode ingest never sees queries longer than that.

</details>

<details>

<summary>Does hash-only mode weaken the query-cost features?</summary>

Barely. `QUERY_ATTRIBUTION_HISTORY` has no query-text column at all and carries `QUERY_PARAMETERIZED_HASH` natively, so cost ranking, cost per execution, regression detection, and tag attribution all work identically. What you lose is the ability to read the offending SQL inside OneLens.

</details>

<details>

<summary>Why does query-level cost lag a day behind everything else?</summary>

`QUERY_ATTRIBUTION_HISTORY` has up to 8 hours of latency — the longest of any view OneLens reads. Combined with a daily pull, yesterday's per-query costs may be incomplete until the following cycle. Query *metadata* (runtime, spill, scan) comes from `QUERY_HISTORY` at 45 minutes and is current.

</details>

<details>

<summary>Will this impact our Snowflake performance?</summary>

No. OneLens runs read-only metadata queries on a dedicated XSMALL warehouse. Your production warehouses are untouched.

</details>

<details>

<summary>Can we connect multiple Snowflake accounts?</summary>

Yes. Run the setup script in each account and connect each separately. Cross-account org-level rollups happen automatically via `ORGANIZATION_USAGE`.

</details>

<details>

<summary>Do we need Enterprise Edition?</summary>

No, but it changes what you get. Cost Intelligence, Warehouse Optimization, and most of Query & Data Optimization work on Standard. Service ROI analysis for Materialized Views, Search Optimization, and Query Acceleration requires Enterprise or higher, because those views don't exist on Standard.

</details>

<details>

<summary>We use Cortex Agents. Is one view enough?</summary>

No — this is a common gap. `CORTEX_AGENT_USAGE_HISTORY` excludes requests originating from Snowflake CoWork, which are recorded separately in `SNOWFLAKE_INTELLIGENCE_USAGE_HISTORY`. Reading only the first understates agent spend. OneLens reads both and reconciles them.

</details>

<details>

<summary>Our account came through a cloud marketplace or a reseller. Will this work?</summary>

**Cloud marketplace** (AWS / Azure / GCP): yes, fully — these are direct Snowflake contracts and `USAGE_IN_CURRENCY_DAILY` populates normally. **Reseller** (capacity sold by a Snowflake partner): yes, but the currency views won't populate. Provide your rates manually in the connection form.

</details>

<details>

<summary>Can we disconnect later?</summary>

Yes — disconnect from the OneLens Connections page, then revoke in Snowflake:

```sql
USE ROLE ACCOUNTADMIN;
DROP USER ONELENS_USER;
DROP ROLE ONELENS_ROLE;
DROP WAREHOUSE ONELENS_WH;
```

Historical OneLens data is retained but no new data syncs after disconnect.

</details>

<details>

<summary>How do we rotate the key?</summary>

Snowflake users support two simultaneous public keys for zero-downtime rotation:

```sql
USE ROLE ACCOUNTADMIN;
-- Add the new key alongside the old one
ALTER USER ONELENS_USER SET RSA_PUBLIC_KEY_2 = '<NEW_PUBLIC_KEY_BODY>';

-- Update OneLens, confirm traffic switches over, then:
ALTER USER ONELENS_USER UNSET RSA_PUBLIC_KEY;
ALTER USER ONELENS_USER SET RSA_PUBLIC_KEY = '<NEW_PUBLIC_KEY_BODY>';
ALTER USER ONELENS_USER UNSET RSA_PUBLIC_KEY_2;
```

Contact OneLens support to coordinate the cutover.

</details>

<details>

<summary>Why do you need MONITOR USAGE on account and MONITOR on warehouse?</summary>

There is no `ACCOUNT_USAGE` view for warehouse configuration. `MONITOR USAGE ON ACCOUNT` gives account-wide usage visibility and the ability to list warehouses; `MONITOR ON WAREHOUSE` exposes size, auto-suspend, and scaling policy. Without them we'd see credit totals but couldn't tell you *why* a warehouse is expensive — which is most of Warehouse Optimization.

</details>

## Need Help?

**Snowflake Documentation:**

* [ACCOUNT\_USAGE views reference](https://docs.snowflake.com/en/sql-reference/account-usage)
* [ORGANIZATION\_USAGE views reference](https://docs.snowflake.com/en/sql-reference/organization-usage)
* [QUERY\_ATTRIBUTION\_HISTORY view](https://docs.snowflake.com/en/sql-reference/account-usage/query_attribution_history)
* [SNOWFLAKE database roles](https://docs.snowflake.com/en/sql-reference/snowflake-db-roles)
* [Key-pair authentication](https://docs.snowflake.com/en/user-guide/key-pair-auth)
* [Network policies](https://docs.snowflake.com/en/user-guide/network-policies)

**Snowflake Support:** <https://community.snowflake.com/>

**OneLens Support:** <support@astuto.ai>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.onelens.cloud/integrations/cloud-and-cost-sources/connecting-to-snowflake.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
