Home / Data Platform / Warehouses

Data PlatformHow-toIntermediate

Optimization: Snowflake warehouse design - sizing, auto-suspend, multi-cluster and query acceleration

Warehouses are where most Snowflake credits go. Separate workloads into purpose-built warehouses, size them by query behaviour rather than habit, set auto-suspend tight, use multi-cluster for concurrency instead of bigger sizes, try query acceleration for outlier scans, and guard everything with resource monitors.

Deepak Bhardwaj4 min read

Applies toSnowflake virtual warehouses (standard, Snowpark-optimized), multi-cluster warehouses, Query Acceleration Service, resource monitors, ACCOUNT_USAGE views

Billing in one paragraph

A running warehouse bills credits per second (with a 60-second minimum each time it starts) at a rate that doubles with each size step. Idle-but-running time costs the same as busy time. So the main levers are: run less idle time, use the right size, and don't run one oversized warehouse for every kind of work.

1. See where credits go

SELECT warehouse_name, ROUND(SUM(credits_used), 1) AS credits
FROM snowflake.account_usage.warehouse_metering_history
WHERE start_time > DATEADD(day, -30, CURRENT_TIMESTAMP())
GROUP BY 1 ORDER BY 2 DESC;

-- idle share: hours billed vs hours with queries
SELECT warehouse_name,
       COUNT(DISTINCT DATE_TRUNC('hour', start_time)) AS hours_with_queries
FROM snowflake.account_usage.query_history
WHERE start_time > DATEADD(day, -30, CURRENT_TIMESTAMP()) AND warehouse_name IS NOT NULL
GROUP BY 1;

2. One warehouse per workload type

Warehouse Workload Typical settings
WH_LOAD Ingestion/COPY, ELT Sized for throughput, auto-suspend 60 s
WH_TRANSFORM dbt/ELT jobs Size by job duration target
WH_BI Dashboards Small-medium, multi-cluster for concurrency
WH_ADHOC Analysts Small, statement timeout, resource monitor
WH_DS Snowpark/ML Snowpark-optimized if memory-heavy

Separation lets you size and attribute cost per workload, and stops a heavy job slowing dashboards.

3. Size by experiment

Run a representative job on two or three sizes:

Size Duration Credits used
M 20 min measure
L 10 min measure
XL 6 min measure

When doubling the size roughly halves duration, the cost is about the same and the job finishes faster. When it doesn't, the bigger size is wasted. Spilling to remote storage (bytes_spilled_to_remote_storage in query history) is a sign the size is too small.

4. Auto-suspend and auto-resume

ALTER WAREHOUSE wh_bi SET AUTO_SUSPEND = 60 AUTO_RESUME = TRUE;
ALTER WAREHOUSE wh_load SET AUTO_SUSPEND = 60;

60 seconds is a good default. Very short values on BI warehouses can drop the local disk cache too often; measure query times before going lower. Warehouses with AUTO_SUSPEND = 0 or NULL never stop. Find them:

SHOW WAREHOUSES;
SELECT "name", "auto_suspend" FROM TABLE(RESULT_SCAN(LAST_QUERY_ID())) WHERE "auto_suspend" IS NULL OR "auto_suspend" = 0 OR "auto_suspend" > 600;

5. Multi-cluster for concurrency

For BI peaks with queuing (queued_overload_time), add clusters instead of a bigger size:

ALTER WAREHOUSE wh_bi SET MIN_CLUSTER_COUNT = 1 MAX_CLUSTER_COUNT = 4 SCALING_POLICY = 'STANDARD';

ECONOMY favours cost (waits longer before adding clusters); STANDARD favours latency. Multi-cluster requires the appropriate Snowflake edition.

6. Query acceleration for outliers

When most queries are fine but a few large scans dominate, Query Acceleration Service can offload parts of eligible queries to shared compute:

SELECT query_id, warehouse_name, eligible_query_acceleration_time
FROM snowflake.account_usage.query_acceleration_eligible
WHERE start_time > DATEADD(day, -7, CURRENT_TIMESTAMP())
ORDER BY eligible_query_acceleration_time DESC LIMIT 20;

ALTER WAREHOUSE wh_adhoc SET ENABLE_QUERY_ACCELERATION = TRUE QUERY_ACCELERATION_MAX_SCALE_FACTOR = 4;

Check eligibility first (the QUERY_ACCELERATION_ELIGIBLE view or SYSTEM$ESTIMATE_QUERY_ACCELERATION).

7. Guardrails

CREATE OR REPLACE RESOURCE MONITOR rm_adhoc WITH CREDIT_QUOTA = 200 FREQUENCY = MONTHLY START_TIMESTAMP = IMMEDIATELY
  TRIGGERS ON 75 PERCENT DO NOTIFY ON 100 PERCENT DO SUSPEND ON 110 PERCENT DO SUSPEND_IMMEDIATE;
ALTER WAREHOUSE wh_adhoc SET RESOURCE_MONITOR = rm_adhoc;
ALTER WAREHOUSE wh_adhoc SET STATEMENT_TIMEOUT_IN_SECONDS = 1800;

Also: limit who can create or resize warehouses (a role owning warehouses, with requests through the platform team).

Tip

Fix the expensive queries before resizing. A missing filter on a huge table makes every size look too small. Check the top queries by execution_time × warehouse size first.

Checklist

  • Credits per warehouse and idle time measured
  • Separate warehouses per workload type
  • Sizes chosen by experiment, spilling checked
  • Auto-suspend ~60 s everywhere
  • Multi-cluster for concurrency where queuing occurs
  • Query acceleration for eligible outliers
  • Resource monitors and statement timeouts