skip to content

A Snowflake warehouse burns credits around the clock though analysts query it only at 9am — why?

level: seniorimportance: should knowfreq 55%

answer

  1. billed for running seconds, not query seconds
  2. find out what stops it going idle
  3. a stuck statement is never idle
  4. something might be polling it every minute
  5. cap it with a monitor next time

basics

~20 s

A Snowflake warehouse bills every second it is running, idle or not. Round-the-clock credits mean it never reaches an idle window: auto-suspend is disabled or too long, a statement is stuck running, or scheduled tasks keep waking it.

solid answer

~40 s

Credits are consumed per running second, so the question is why the warehouse never becomes idle long enough to suspend. Work through the causes in order: (1) `AUTO_SUSPEND` is `NULL`/0 — disabled during some past investigation and never restored; (2) `AUTO_SUSPEND` is set but far longer than the gaps between queries, so it never fires; (3) a **runaway or hung statement** is still executing, and auto-suspend only fires on an idle warehouse — check running queries and set `STATEMENT_TIMEOUT_IN_SECONDS`; (4) scheduled **tasks**, Streams-driven jobs or a monitoring tool poll the warehouse every minute, resetting the idle timer; (5) the warehouse is in maximized multi-cluster mode (`MIN_CLUSTER_COUNT` > 1), so whenever it is up you are paying for every cluster. Note what is *not* a cause: idle open sessions do not hold a warehouse running.

code

sql · 8 lines
sql
-- what is actually configured on every warehouse
SHOW WAREHOUSES;

-- durable fixes on the offender
ALTER WAREHOUSE etl_wh SET
  AUTO_SUSPEND = 120,
  AUTO_RESUME  = TRUE,
  STATEMENT_TIMEOUT_IN_SECONDS = 3600;

go deeper

for a junior

Remember that a Snowflake warehouse bills for every running second, so the first thing to check is whether AUTO_SUSPEND is set at all.

for a middle

Explain each way a warehouse fails to reach an idle window — disabled or oversized suspend delay, a still-running statement, frequent tasks — and what evidence distinguishes them.

for a senior

Show a full diagnosis with the evidence you would pull, then the durable fixes: matched suspend values, statement timeouts, workload separation and a resource monitor as backstop.

for a principal

Own prevention at account scale: warehouse creation standards, an audit for suspend-disabled warehouses, budget alerting on running hours, and clear ownership of every warehouse's cost.

## Frame the problem correctly Snowflake bills a virtual warehouse for **every second it is in the running state**, regardless of whether a query is executing, with a 60-second minimum per start. So "burning credits all day" is never mysterious: the warehouse is up all day. The diagnostic question is *what keeps it up*, and there are only a few possibilities. ## 1. Auto-suspend is disabled `AUTO_SUSPEND = NULL` or `0` means the warehouse runs until a human suspends it. This is the single most common cause and it usually has the same history: someone disabled it while debugging cache-warmth complaints, or created the warehouse from a script that omitted the property. Check it directly: ```sql SHOW WAREHOUSES; -- inspect auto_suspend / auto_resume per warehouse ``` Audit the whole account for this, not just the warehouse that showed up on the bill. ## 2. The suspend delay is longer than the gaps between queries `AUTO_SUSPEND = 3600` on a warehouse that gets a query every 40 minutes never suspends — every arrival resets the idle timer. The setting is present, looks configured, and does nothing. Compare the delay against the actual arrival pattern in query history rather than against intuition. ## 3. A statement is still running Auto-suspend fires only when the warehouse is **idle**. A query stuck for hours — a runaway cross join, a client that opened a cursor and stopped fetching, a load waiting on something external — keeps the warehouse busy and therefore billing. Look for long-running statements in query history or `SHOW ... ` running-query surfaces, and then prevent recurrence with a statement timeout: ```sql ALTER WAREHOUSE etl_wh SET STATEMENT_TIMEOUT_IN_SECONDS = 3600; ``` The account default for `STATEMENT_TIMEOUT_IN_SECONDS` is very high (48 hours), which is effectively no protection; setting a realistic per-warehouse value is standard hygiene. ## 4. Something is polling the warehouse Scheduled **tasks**, Stream-consuming jobs, ingestion pipelines, a BI tool's health check, or a monitoring dashboard that runs a query every minute will all keep the idle timer from ever expiring. Each individual query is trivial; the effect is a warehouse that runs 24 hours for a few minutes of real work. The fix is architectural: move high-frequency polling to a dedicated tiny warehouse whose cost you accept, batch the schedule so the warehouse gets real idle windows, or replace the polling with metadata-only checks that need no warehouse at all. ## 5. Maximized multi-cluster mode If `MIN_CLUSTER_COUNT` is greater than 1, then whenever the warehouse is running it runs *that many* clusters, each billing at the size's credit rate. The warehouse still suspends when fully idle, but a mostly-idle maximized warehouse multiplies whatever idle time remains. Check the cluster counts before concluding the size is the problem. ## What is not the cause Two beliefs come up in interviews and both are wrong: - **Idle sessions.** An open connection or a logged-in user does not keep a warehouse running. Only executing statements do. - **Cached results.** Serving a query from the results cache in the cloud services layer does not require the warehouse and does not resume it. ## Turning the diagnosis into a fix Once you know which cause it is, the remedies are ordered by permanence: 1. Restore `AUTO_SUSPEND` to a value matched to the workload's arrival pattern, and `AUTO_RESUME = TRUE` so nothing breaks for users. 2. Set `STATEMENT_TIMEOUT_IN_SECONDS` on every warehouse so no single statement can hold compute indefinitely. 3. Separate workloads: give polling, ETL and interactive users their own warehouses so one pattern's arrival rate does not hold another's compute up. 4. Attach a **resource monitor** with a credit quota and a suspend trigger, so the next occurrence has a ceiling instead of a bill. 5. Alert on the pattern, not just the total: a warehouse whose running hours per day approach 24 is the signal, and it appears long before the invoice does. ## Why interviewers like this question It is the most common real Snowflake incident, and it separates people who have operated an account from people who have read the docs. A strong answer enumerates causes, names the evidence for each, and finishes with the guardrails that stop it recurring — not just "turn auto-suspend on."

  • Why does a statement timeout matter even when auto-suspend is correctly configured?
    Because auto-suspend only fires on an idle warehouse. A single hung or runaway statement keeps the warehouse executing and therefore billing indefinitely, and no suspend delay will ever elapse. STATEMENT_TIMEOUT_IN_SECONDS bounds that exposure; the account default is effectively no protection, so set a realistic per-warehouse value.
  • A task running every minute keeps a warehouse alive all day. What are your options?
    Give the task its own X-Small warehouse so the cost is bounded and the interactive warehouse can suspend; batch the schedule so real idle windows exist; or replace the polling with something that needs no warehouse, such as a metadata check. Leaving a minute-frequency task on a large shared warehouse is the expensive choice.
  • How would you find every warehouse in the account with this problem rather than just the one on the bill?
    Enumerate warehouses and inspect their auto-suspend, auto-resume and cluster-count properties, then compare each warehouse's running hours per day against its actual query activity. A warehouse approaching 24 running hours with a handful of queries is the signature, and it shows up well before the invoice does.

saying these in an interview costs you the question

  • Claiming idle open sessions keep a warehouse running
  • Assuming a warehouse only bills while a query executes
  • Suggesting a smaller size instead of finding what holds it up
  • Ignoring scheduled tasks that reset the idle timer every minute
  • Fixing it once without adding a statement timeout or monitor

context