Free tool

What does each Snowflake warehouse cost you a month?

Put in each warehouse’s size, generation, clusters, hours of queries, resumes and auto-suspend, and see its credits and cost a month, how much of it is idle time before the warehouse suspends, and what one size down would cost, at Snowflake’s list prices.

Warehouse 1

Query hours are the time queries actually run; the wait before auto-suspend is added on top. Auto-suspend 0 means the warehouse never suspends. Not sure of the numbers? One query against ACCOUNT_USAGE returns them for every warehouse.

Account

List prices are on demand in AWS US East. On a capacity contract, pick “Contract price” and enter what you pay per credit.

List prices, not a quote. Your inputs never leave this browser. They are only copied into the part of the page address after the #, which browsers do not send anywhere, so you can share the result as a link.

Your real numbers

Read every warehouse’s inputs with one query

Snowflake records the credits each warehouse used in ACCOUNT_USAGE.WAREHOUSE_METERING_HISTORY, including how many of them ran queries, and every resume in WAREHOUSE_EVENTS_HISTORY. Run this in a Snowsight worksheet with Run All. It reads metadata only, never your tables, and returns one row per warehouse: its size, generation and current AUTO_SUSPEND from SHOW WAREHOUSES, its last 30 days of credits and the idle share of them, and the hours and resumes a day the calculator takes. Each row ends in a link that opens this page with that warehouse filled in, and the last column opens your five most expensive warehouses at once.

Snowflake: every warehouse as calculator inputs · vendor docs
-- Your Snowflake warehouses as cost calculator inputs, one row each: size,
-- generation, AUTO_SUSPEND, last-30-day credits, the share of them that was idle,
-- and the active hours and resumes a day the calculator takes.
-- Reads metadata only. Needs a role that can read SNOWFLAKE.ACCOUNT_USAGE, which
-- lags by up to three hours. In Snowsight use Run All: the SELECT reads the
-- result of SHOW WAREHOUSES through LAST_QUERY_ID(), so nothing may run between them.
SHOW WAREHOUSES;

WITH wh AS (
  SELECT
    "name" AS warehouse_name,
    "size" AS size,
    CASE
      WHEN UPPER(REPLACE("size", '-', '')) IN ('XSMALL') THEN 'XS'
      WHEN UPPER(REPLACE("size", '-', '')) IN ('SMALL') THEN 'S'
      WHEN UPPER(REPLACE("size", '-', '')) IN ('MEDIUM') THEN 'M'
      WHEN UPPER(REPLACE("size", '-', '')) IN ('LARGE') THEN 'L'
      WHEN UPPER(REPLACE("size", '-', '')) IN ('XLARGE') THEN 'XL'
      WHEN UPPER(REPLACE("size", '-', '')) IN ('2XLARGE', 'XXLARGE', 'X2LARGE') THEN '2XL'
      WHEN UPPER(REPLACE("size", '-', '')) IN ('3XLARGE', 'XXXLARGE', 'X3LARGE') THEN '3XL'
      WHEN UPPER(REPLACE("size", '-', '')) IN ('4XLARGE', 'X4LARGE') THEN '4XL'
    END AS size_code,
    CASE
      WHEN UPPER(REPLACE("size", '-', '')) IN ('XSMALL') THEN 1
      WHEN UPPER(REPLACE("size", '-', '')) IN ('SMALL') THEN 2
      WHEN UPPER(REPLACE("size", '-', '')) IN ('MEDIUM') THEN 4
      WHEN UPPER(REPLACE("size", '-', '')) IN ('LARGE') THEN 8
      WHEN UPPER(REPLACE("size", '-', '')) IN ('XLARGE') THEN 16
      WHEN UPPER(REPLACE("size", '-', '')) IN ('2XLARGE', 'XXLARGE', 'X2LARGE') THEN 32
      WHEN UPPER(REPLACE("size", '-', '')) IN ('3XLARGE', 'XXXLARGE', 'X3LARGE') THEN 64
      WHEN UPPER(REPLACE("size", '-', '')) IN ('4XLARGE', 'X4LARGE') THEN 128
    END
      * IFF(TO_VARCHAR("generation") = '2' OR "resource_constraint" = 'STANDARD_GEN_2', 1.35, 1) AS credits_per_hour,
    IFF(TO_VARCHAR("generation") = '2' OR "resource_constraint" = 'STANDARD_GEN_2', 'gen2', 'gen1') AS gen,
    -- 0 or NULL means the warehouse never suspends itself.
    COALESCE("auto_suspend", 0) AS auto_suspend,
    "max_cluster_count" AS max_clusters
  FROM TABLE(RESULT_SCAN(LAST_QUERY_ID()))
  -- Standard warehouses only: Snowpark-optimized ones bill at other rates.
  WHERE "type" = 'STANDARD'
),
metering AS (
  SELECT
    warehouse_name,
    SUM(credits_used_compute) AS compute_credits,
    -- Credits spent running queries, which leaves out idle time.
    SUM(credits_attributed_compute_queries) AS query_credits,
    COUNT(DISTINCT IFF(credits_used_compute > 0, TO_DATE(start_time), NULL)) AS active_days
  FROM SNOWFLAKE.ACCOUNT_USAGE.WAREHOUSE_METERING_HISTORY
  WHERE start_time >= DATEADD(day, -30, CURRENT_TIMESTAMP())
  GROUP BY warehouse_name
),
resumes AS (
  -- One row per warehouse resume, automatic or manual. Cluster-level events
  -- carry a cluster number, so they are not counted twice.
  SELECT warehouse_name, COUNT(*) AS resumes
  FROM SNOWFLAKE.ACCOUNT_USAGE.WAREHOUSE_EVENTS_HISTORY
  WHERE "TIMESTAMP" >= DATEADD(day, -30, CURRENT_TIMESTAMP())
    AND event_state = 'STARTED'
    AND event_reason IN ('WAREHOUSE_AUTORESUME', 'WAREHOUSE_RESUME')
    AND cluster_number IS NULL
  GROUP BY warehouse_name
),
inputs AS (
  SELECT
    wh.*,
    m.compute_credits,
    m.compute_credits - COALESCE(m.query_credits, m.compute_credits) AS idle_credits,
    -- The calculator takes 1 to 31 days a month and 0 to 24 hours a day.
    LEAST(GREATEST(m.active_days, 1), 31) AS days,
    -- Query time in cluster-hours, so a multi-cluster warehouse goes in as one cluster.
    LEAST(COALESCE(m.query_credits, m.compute_credits) / wh.credits_per_hour / LEAST(GREATEST(m.active_days, 1), 31), 24) AS hours,
    COALESCE(r.resumes, 0) / LEAST(GREATEST(m.active_days, 1), 31) AS resumes_per_day
  FROM wh
  JOIN metering AS m ON m.warehouse_name = wh.warehouse_name
  LEFT JOIN resumes AS r ON r.warehouse_name = wh.warehouse_name
  -- 5XL and 6XL are left out: the calculator does not price them.
  WHERE wh.size_code IS NOT NULL AND m.compute_credits > 0
),
wh_rows AS (
  SELECT
    *,
    '&wh=' || REGEXP_REPLACE(warehouse_name, '[^A-Za-z0-9_$]', '_')
      || '&size=' || size_code
      || '&gen=' || gen
      || '&clusters=1'
      || '&hours=' || TO_VARCHAR(hours::NUMBER(38, 2))
      || '&resumes=' || TO_VARCHAR(resumes_per_day::NUMBER(38, 1))
      || '&suspend=' || TO_VARCHAR(LEAST(auto_suspend, 86400))
      || '&days=' || TO_VARCHAR(days) AS params,
    ROW_NUMBER() OVER (ORDER BY compute_credits DESC) AS rn
  FROM inputs
),
-- The five warehouses that used the most credits, in one link.
top5 AS (
  SELECT 'https://lp-data.cloud/tools/snowflake-warehouse-cost-calculator#' || SUBSTR(LISTAGG(params, '') WITHIN GROUP (ORDER BY rn), 2)
    || '&via=sql-snowflake-calc' AS url
  FROM wh_rows
  WHERE rn <= 5
)
SELECT
  warehouse_name,
  size,
  gen,
  auto_suspend AS auto_suspend_seconds,
  max_clusters,
  ROUND(compute_credits, 1) AS compute_credits_30d,
  ROUND(idle_credits, 1) AS idle_credits_30d,
  ROUND(DIV0(idle_credits, compute_credits) * 100) AS idle_pct,
  days AS active_days,
  ROUND(hours, 2) AS query_hours_per_active_day,
  ROUND(resumes_per_day, 1) AS resumes_per_active_day,
  'https://lp-data.cloud/tools/snowflake-warehouse-cost-calculator#' || SUBSTR(params, 2) || '&via=sql-snowflake-calc' AS calculator_url,
  top5.url AS top5_calculator_url
FROM wh_rows CROSS JOIN top5
ORDER BY rn;

The idle_credits_30d column is Snowflake’s own figure: compute credits less the credits attributed to queries. Compare it with the idle cost the calculator shows; if the measured figure is much higher, the warehouse is being kept awake by something other than its auto-suspend, such as a tool polling it. For the full method on BigQuery, Snowflake and Redshift, see Measure your own warehouse workload from query history, in one query per platform.

Method

How it is calculated

Snowflake bills a running warehouse in credits, per second, with a 60-second minimum each time it starts or resumes. A suspended warehouse bills nothing. Every price is Snowflake’s on-demand list price in AWS US East, shown with its source under “Prices used”.

Credits an hour by warehouse size

Standard warehouses. Each size up doubles the credits an hour and the compute.
SizeGen 1 credits/hGen 2 credits/h (AWS)Enterprise $/h, Gen 1
XS11.35$3.00
S22.7$6.00
M45.4$12.00
L810.8$24.00
XL1621.6$48.00
2XL3243.2$96.00
3XL6486.4$192.00
4XL128172.8$384.00

Formulas

  • Credits an hour = the size’s credits × 1.35 for Gen 2 × clusters running.
  • Each resume starts a session. A day’s query hours are shared across its resumes, and each session bills its share plus the auto-suspend wait, and never less than 60 seconds: billed seconds per resume = max(60, query seconds per resume + auto-suspend).
  • Billed hours a day = resumes × billed seconds per resume ÷ 3,600, at most 24. With auto-suspend 0 the warehouse never suspends and bills 24.
  • Idle hours a day = billed hours − query hours.
  • Credits a month = credits an hour × billed hours × days. Idle credits = credits an hour × idle hours × days.
  • Cost = credits × the price per credit: Standard $2.00, Enterprise $3.00, Business Critical $4.00, or your contract price.
  • Storage = TB × $23.00 a month, once for the account.

The what-ifs

  • Auto-suspend at 60 seconds: the same warehouse with only the wait changed.
  • One size down: half the credits an hour, and every query assumed to take twice as long, which is the same work for the same query credits. What it saves is idle time and the minimum per resume, billed at the smaller rate. The break-even is how much longer queries can run on the smaller size before it stops being cheaper. A bigger warehouse only pays off if it more than halves runtime.

Not included: cloud services credits (billed only above 10% of the day’s warehouse credits), serverless features such as Snowpipe, tasks and clustering, query acceleration, Snowpark-optimized and interactive warehouses, data transfer, and 5XL and 6XL sizes.

Worked example

TRANSFORM_WH is a Medium Gen 1 warehouse (4 credits an hour) that runs 8 hours of queries a day across 20 resumes, with a 600-second auto-suspend, 30 days a month, on Enterprise.

  • Query time: 4 × 8 hours × 30 days = 960 credits.
  • Idle time: 20 resumes × 600 seconds ÷ 3,600 × 4 × 30 days = 400 credits, 29% of the total.
  • Total: 1,360 credits × $3.00 = $4,080 a month, of which $1,200 is idle.
  • Dropping auto-suspend on TRANSFORM_WH from 600s to 60s saves about $1,080 a month (26% of its bill).
  • One size down (S), if every query takes twice as long: saves about $600 a month. It only costs more if queries run more than 2.42× longer on S.

29% of this bill is the warehouse waiting to suspend. That is the first thing to check on any account, before resizing anything. Open this example in the calculator.

Sources

Prices used

On demand, AWS US East (Northern Virginia). Gen 2 standard warehouses on AWS use 1.35 times the Gen 1 credits an hour, from Table 1(b) of the same document.
PlatformItemList price (USD)Applies toChecked
SnowflakeCredit, Standard edition$2.00 per creditOn demand, AWS US East (Northern Virginia)2026-10-14
SnowflakeCredit, Enterprise edition$3.00 per creditOn demand, AWS US East (Northern Virginia)2026-10-14
SnowflakeCredit, Business Critical edition$4.00 per creditOn demand, AWS US East (Northern Virginia)2026-10-14
SnowflakeStorage$23.00 per TB-monthOn demand, AWS US East (Northern Virginia); billed on compressed size2026-10-14

Snowflake warehouse sizes, credits per hour: XS 1 · S 2 · M 4 · L 8 · XL 16 · 2XL 32 · 3XL 64 · 4XL 128. Same source as the Snowflake rates.

Questions

Snowflake warehouse cost

When is a bigger Snowflake warehouse cheaper?

Each size up doubles the credits an hour, so a bigger warehouse only costs the same if every query finishes in half the time, and only costs less if it finishes in less than half. Query time costs about the same at every size when the work scales perfectly; what changes is idle time, because the wait before auto-suspend and the 60-second minimum are billed at the bigger size's rate. So a bigger size pays off for heavy queries that really do run twice as fast, or that spill to disk on the smaller one, and rarely for small, frequent queries. The "one size down" line in the calculator shows how much slower queries could get before the smaller size stops being cheaper.

What is the 60-second minimum, and how does auto-suspend affect cost?

Snowflake bills a running warehouse per second, but every time it starts or resumes it bills at least one minute. After the last query it keeps running, and billing, for the auto-suspend time before it suspends. With a 600-second auto-suspend, every resume costs at least ten idle minutes on top of the queries. With 20 resumes a day that is more than three idle hours a day. Setting auto-suspend to 60 seconds removes most of that; going lower saves little, because each resume bills the minimum anyway, and it loses the warehouse cache sooner.

Gen1 or Gen2: which Snowflake warehouse costs less?

Gen 2 standard warehouses use 1.35 times the credits an hour of Gen 1 on AWS (an X-Small is 1.35 credits an hour instead of 1; 1.25 times on Azure). They are cheaper only if your queries finish more than 26% faster on them, which is common for DML-heavy work like MERGE, UPDATE and DELETE and less common for simple scans. Test on a representative workload: switch one warehouse, compare a week of credits per run, and keep whichever is lower.

Multi-cluster warehouses or a bigger size?

Scale up (a bigger size) when single queries are slow. Scale out (more clusters) when many queries queue at the same time, as with dashboards and many analysts at once. Every running cluster bills the full credits of its size, so two Medium clusters cost the same as one Large for the time both run. In the calculator, set the clusters to the average number running while the warehouse is up, not the maximum.

Why are cloud services credits usually free?

Cloud services (compilation, metadata, the result cache) use credits too, but Snowflake only bills the part that is more than 10% of the day's warehouse credits. Most accounts stay under that, so the calculator leaves them out. Accounts with very many small queries or heavy metadata work can go over it; WAREHOUSE_METERING_HISTORY shows the cloud services credits per warehouse.

Why is storage billed separately?

Snowflake separates storage from compute: storage is a flat price per TB a month of compressed data, $23.00 on demand in AWS US East, including Time Travel and Fail-safe, whether or not any warehouse runs. Warehouse size, auto-suspend and edition do not change it, so the calculator adds it once for the account.

Where do the prices come from, and do they include discounts?

From Snowflake's Service Consumption Table: the on-demand price per credit for Standard ($2.00), Enterprise ($3.00) and Business Critical ($4.00) in AWS US East, the credits an hour per warehouse size and the Gen 2 rates. Capacity contracts are priced per customer, so you can type in your own price per credit instead.

Measure your workload from query history first: Measure your own warehouse workload from query history, in one query per platform. And to see how the same workload compares across platforms: BigQuery vs Snowflake vs Redshift Serverless: what the same workload costs on each.

The Divergence Point

Where the numbers stop agreeing, and what to do about it. One email a month on data quality, reconciliation and building warehouses that survive contact with a real business. No recycled LinkedIn posts.

Want the whole bill looked at?

Warehouse settings are one lever. The data stack audit also covers the models, schedules and dashboards that keep warehouses busy, and ends in a ranked plan.