The six places Snowflake spend leaks, and exactly how to find and fix each one — with the queries and settings we use on real accounts. No gate, no email required. If you only do the first two, you will likely move the bill.
Queries below read from the SNOWFLAKE.ACCOUNT_USAGE share, which has some latency (typically up to a few hours). Pricing and a few defaults change over time — verify the specifics against current Snowflake docs and your own contract.
1. Idle compute (auto-suspend)
A warehouse keeps billing after the last query finishes. The web UI default when you create a warehouse is a 10-minute auto-suspend, which means up to 10 minutes of paid idle time after every burst of work. (Verify the current default for your account — Snowflake has changed UI defaults over time.)
Find it
Inspect auto-suspend on every warehouse
SHOW WAREHOUSES;
-- Look at the auto_suspend column (seconds).
-- Anything 300+ on an interactive warehouse is usually worth tightening.
Fix it
Tighten to 60s for interactive / BI warehouses
ALTER WAREHOUSE bi_wh SET
AUTO_SUSPEND = 60 -- seconds of idle before it suspends
AUTO_RESUME = TRUE; -- wakes automatically on the next query
Keep auto-suspend a little higher (e.g. 120–300s) on warehouses that benefit from a warm local cache, and lower (60s) on bursty interactive ones. Billing is per-second with a 60-second minimum each time a warehouse resumes, so very short suspends on a constantly-pinged warehouse can backfire — measure before and after.
2. Oversized warehouses
A warehouse provisioned for a worst-case job runs at that size all day. Each size step (XS, S, M, L, XL, 2XL...) roughly doubles credits-per-hour, so one unnecessary size up is ~2x the compute cost for that workload.
Find it
Find your biggest credit consumers (last 30 days)
SELECT warehouse_name,
SUM(credits_used) AS credits,
SUM(credits_used_compute) AS compute,
SUM(credits_used_cloud_services) AS cloud_services
FROM snowflake.account_usage.warehouse_metering_history
WHERE start_time >= DATEADD('day', -30, CURRENT_TIMESTAMP())
GROUP BY 1
ORDER BY credits DESC;
Fix it
Right-size to the workload, then verify it still performs
ALTER WAREHOUSE etl_wh SET WAREHOUSE_SIZE = 'MEDIUM';
-- Re-run the representative jobs and compare execution_time + credits.
-- A larger warehouse finishes faster, so the right comparison is
-- credits-per-job, not credits-per-hour.
Bigger is not always pricier per job: a query that runs 4x faster on a warehouse that costs 2x per hour is cheaper overall. Decide by credits-per-job on representative queries, and split mixed workloads (heavy ETL vs. light BI) onto separate warehouses so each can be sized independently.
3. Inefficient queries (poor pruning)
Full table scans and exploding joins burn credits and slow everyone down. The tell is a query that scans nearly all micro-partitions to return a few rows.
SELECT query_id,
warehouse_name,
partitions_scanned,
partitions_total,
bytes_scanned,
execution_time
FROM snowflake.account_usage.query_history
WHERE start_time >= DATEADD('day', -7, CURRENT_TIMESTAMP())
AND partitions_total > 0
AND partitions_scanned >= partitions_total * 0.9 -- scanning almost everything
ORDER BY bytes_scanned DESC
LIMIT 50;
Fix it
Fix the heavy hitters, not every query
-- Common fixes, in rough order of effort vs. payoff:
-- * Filter on the columns data is naturally ordered by (load/event date).
-- * Select only needed columns — avoid SELECT * on wide tables.
-- * Add a clustering key only on very large, frequently-filtered tables:
ALTER TABLE events CLUSTER BY (event_date);
-- * Replace repeated heavy aggregations with a scheduled summary table.
A small number of queries usually drives a large share of spend, so start at the top of that list. Clustering and materialized views have their own ongoing serverless cost (see lever 4) — only add them where the read savings clearly outweigh the maintenance cost.
4. Unmonitored serverless features
Automatic Clustering, Materialized Views, Search Optimization, Snowpipe, and Query Acceleration all bill serverless credits independent of your warehouses — and are easy to leave running where they no longer pay off.
Find it
See what serverless features are actually costing
SELECT service_type,
SUM(credits_used) AS credits
FROM snowflake.account_usage.metering_history
WHERE start_time >= DATEADD('day', -30, CURRENT_TIMESTAMP())
GROUP BY 1
ORDER BY credits DESC;
-- service_type includes AUTO_CLUSTERING, MATERIALIZED_VIEW,
-- SEARCH_OPTIMIZATION, PIPE, QUERY_ACCELERATION, and more.
Fix it
Turn off what no longer earns its keep
-- Example: drop auto-clustering on a table where it is not helping
ALTER TABLE big_table SUSPEND RECLUSTER;
-- Example: remove search optimization where queries no longer use it
ALTER TABLE big_table DROP SEARCH OPTIMIZATION;
These features are genuinely valuable on the right tables — the goal is to attribute their cost and keep them only where the read-side savings are bigger than the maintenance credits. Re-check after schema or query-pattern changes, because yesterday’s win can become today’s waste.
5. Storage and Time Travel
Storage is usually a smaller line than compute, but long Time Travel retention on large, churny tables quietly multiplies what you store. Fail-safe (7 days, not configurable) adds more on top.
Find it
Find your largest tables and their Time Travel / Fail-safe footprint
SELECT table_catalog,
table_schema,
table_name,
active_bytes,
time_travel_bytes,
failsafe_bytes
FROM snowflake.account_usage.table_storage_metrics
ORDER BY (time_travel_bytes + failsafe_bytes) DESC
LIMIT 50;
Fix it
Match retention to how far back you actually recover
-- Shorten Time Travel on large staging/transient data:
ALTER TABLE staging_events SET DATA_RETENTION_TIME_IN_DAYS = 1;
-- Use TRANSIENT tables for reload-able staging (no Fail-safe):
CREATE TRANSIENT TABLE staging_events_t (...);
Default Time Travel is 1 day on Standard edition and configurable up to 90 days on Enterprise+. Don’t cut retention below your real recovery window — the point is to stop paying 30–90 days of history on data you would never restore. Confirm current pricing (storage is roughly $23/TB/month on-demand, but it varies by cloud, region, and capacity commitment).
6. No guardrails (resource monitors)
No credit budgets, no per-team attribution, and no alerts means overspend is only discovered on the monthly invoice — when it is too late to do anything about it.
Find it
Check whether any resource monitors exist at all
SHOW RESOURCE MONITORS;
-- An empty or near-empty result is the finding.
Fix it
Put a budget with notify-then-suspend triggers in place
CREATE OR REPLACE RESOURCE MONITOR monthly_cap
WITH CREDIT_QUOTA = 1000 -- your monthly budget in credits
FREQUENCY = MONTHLY
START_TIMESTAMP = IMMEDIATELY
TRIGGERS ON 80 PERCENT DO NOTIFY
ON 100 PERCENT DO SUSPEND
ON 110 PERCENT DO SUSPEND_IMMEDIATE;
ALTER WAREHOUSE etl_wh SET RESOURCE_MONITOR = monthly_cap;
Use NOTIFY-only monitors on production warehouses you cannot afford to suspend, and hard SUSPEND caps on dev/sandbox. Attribute spend by team or workload (separate warehouses, or query tags) so the budget conversation has an owner — guardrails that nobody owns quietly get raised.
The 8-step checklist
Run it in order. The early steps are the cheapest to do and usually the highest payoff.
1Audit auto-suspend on every warehouse; tighten interactive ones toward 60s.
2Rank warehouses by 30-day credits; right-size the top consumers by credits-per-job.
3Split heavy ETL and light BI onto separate, independently-sized warehouses.
4Pull the top 50 poorly-pruned queries; fix filters, projections, and the worst joins.
5Attribute serverless spend (clustering, MVs, search optimization) and prune what no longer pays.
6Match Time Travel retention to your real recovery window; use transient tables for reloadable staging.
7Create resource monitors with notify-then-suspend triggers and a real monthly budget.
8Stand up a weekly cost view from ACCOUNT_USAGE so savings hold instead of creeping back.
Want us to run this against your account?
A free Snowflake cost assessment turns this playbook into a prioritized, numbers-backed savings roadmap for your specific warehouses and queries — yours to act on with us or on your own.