Snowflake cost conversations usually start at the warehouse or the monthly bill. A warehouse consumed more credits this week. Finance wants to know why. The dashboard shows runtime, but not the reason the runtime grew.
One of the more common reasons is query spillage. When a query cannot keep its intermediate results in warehouse memory, Snowflake writes that data to local disk, and if necessary to remote cloud storage. The query still completes. Nothing fails. The warehouse simply stays active longer, and credits accrue against that extra time.
Spillage does not appear as a line item. It appears as a transformation that used to finish in forty seconds and now runs for eight minutes, a dashboard refresh that keeps a warehouse from auto-suspending, or a nightly job whose credit share has quietly doubled. The cost pattern is mechanical: memory pressure, disk or remote spillage, longer execution, more warehouse runtime, higher Snowflake credits. This article stays on that mechanism. The question of who owns the fix, and how to keep the cost from returning, is covered in a companion piece on spillage as a governance problem.
How spillage turns into Snowflake credits
Snowflake virtual warehouses consume credits while they are running. Credit consumption is a function of warehouse size and elapsed time, not of whether the SQL looked reasonable. A query that finishes in thirty seconds on a Medium warehouse costs less than the same query running for ten minutes, even if both return the same result. Runtime is the cost surface.
Most efficient queries complete their work in memory. That is the fastest path, and therefore usually the cheapest path for a given warehouse size. When an operation creates more intermediate data than the warehouse can hold—through joins, sorts, aggregations, window functions, or large scans—Snowflake spills that data to local storage attached to the warehouse. If local capacity is still not enough, it spills to remote cloud storage. Snowflake notes that both affect performance, with remote storage generally producing the more severe degradation.
That degradation is the cost event. Local spillage adds disk I/O. Remote spillage is typically slower still because intermediate data has to move through cloud storage. Every extra second the warehouse stays up is billed. If the spilling query is the last work on the warehouse, it can also delay auto-suspend. If it shares the warehouse with other jobs, it can keep compute running for everyone else, or push concurrent queries into queueing that extends their runtime too. The bill does not say “remote spill.” It says the warehouse ran.
This is why treating a spilling query as “just slow” understates the problem. A slow query is often a cost signal. The useful metrics are the ones that connect the two: bytes_spilled_to_local_storage, bytes_spilled_to_remote_storage, execution time, and how often the query runs. Query Profile then shows which operators produced the intermediate data. The spill is the mechanism. Credits are the consequence.
Why some spills cost more than others
Not every spill moves the bill. A one-off analyst query that spills once is usually noise. An hourly dbt model that spills to remote storage is a cost pattern. Frequency is what turns a performance annoyance into a credit problem: the same extra minutes, charged every run, on a warehouse that may also stay up between those runs.
Warehouse size multiplies the effect. An extra five minutes on an X-Small warehouse is a different invoice from an extra five minutes on a 2X-Large. Remote spillage on a large warehouse is therefore a high-priority cost candidate even before anyone debates whether the SQL is elegant. Shared warehouses add a second multiplier. One memory-heavy job can prevent auto-suspend, delay a dashboard cluster, or force other workloads to wait—none of which appears as “spillage” in a monthly summary, but all of which consume credits.
The practical ranking is therefore not “every query with nonzero spilled bytes.” It is recurring remote spills, spills on larger warehouses, and spills that keep a shared warehouse from going idle. Those are the rows that change spend.
Workload patterns that create expensive intermediate data
Spillage is a memory symptom. The cost usually starts in how much intermediate data the query creates.
Joins are the most common source. When join keys are not selective, or one side contains many duplicate values, the intermediate result can be far larger than either input. A nightly sales transformation that joins orders to a dimension with duplicate keys can explode into a sort or hash that no longer fits in memory. The SQL may still be “correct” in the sense that it returns rows. It is expensive because it manufactured too many of them.
Large ORDER BY operations spill when Snowflake has to sort more data than the warehouse can hold. High-cardinality GROUP BY work does the same, especially on wide fact tables. SELECT * on those tables makes it worse: unused columns travel through execution, increasing memory pressure even when downstream logic only needs a handful of fields. Queries that scan entire tables instead of filtering early create more of that intermediate data in the first place. In each case the warehouse is not “too small” in the abstract. It is being asked to hold a working set the query never needed to produce.
How to reduce the credit impact
Start with evidence, not with a larger warehouse. Query History will show which statements spilled, how many bytes went to local versus remote storage, how long they ran, and how often they execute. Prioritize remote spills that repeat. A query that spills 200 GB to remote storage once a month is a different cost object from one that does it every dashboard refresh.
Then reduce the working set. Apply filters earlier. Drop columns the later stages do not use. Pre-aggregate or deduplicate before a join if the outer query is inheriting duplicate keys. Check whether a GROUP BY is aggregating at a lower grain than the business question requires. Smaller intermediate data is the most reliable way to cut both spill volume and runtime, which is what actually reduces credits.
Warehouse sizing still matters, but it is a cost trade-off rather than a default fix. A smaller warehouse is cheaper per hour, yet a memory-heavy job that spills for twenty minutes can cost more than a larger warehouse that finishes in two. Snowflake cautions that larger is not necessarily faster for every workload. The test is total credits for the job, not credits per hour. Separating workload classes helps the same measurement: if a spilling batch job shares a warehouse with interactive BI, you are paying both for the spill and for everything that could not suspend while it ran. Matching warehouse to workload type is often cheaper than making one warehouse large enough for the worst query on it. For the sizing framework, see warehouse right-sizing.
Signals worth ranking, in practice:
- Bytes spilled to remote storage, then local storage
- Execution time versus a recent baseline for the same query
- Run frequency—hourly and dashboard-refresh jobs first
- Warehouse size, because each extra minute costs more at larger sizes
- Whether the warehouse stayed active after the spilling query finished
A faster query is not automatically a cheaper warehouse
The original problem is measurable, so the fix should be too. Did remote spillage disappear? Did runtime fall? Did warehouse credits for that workload fall, or did a resize simply spend more per hour to buy back the minutes? Did moving the query off a shared warehouse reduce the spill but increase spend somewhere else? A merged rewrite that still runs just as long has not reduced cost. A larger warehouse that finishes faster has only helped if total credits declined.
Recurring queries dominate this math. Optimizing a statement that executes once is a quality-of-life change. Optimizing a statement that executes every hour is a budget change. That is also why warehouse-level dashboards are incomplete. They show where credits were consumed. They do not show that one spilling transformation, or one BI refresh storm, is the reason the warehouse never quite suspends. Cost control has to get down to the workload that created the intermediate data.
This is the part Anavsan is built to make durable: connect spilling queries to credit impact, not only to query duration, and show whether an intervention actually moved spend. Native telemetry can tell you that bytes spilled. It does not by itself prove that the bill improved. Once that cost evidence exists, the next problem is operational rather than mechanical—getting the right owner to act, and keeping the cheaper runtime from drifting back. That is the companion argument in why detecting spillage is only half the problem.
Start with the queries that keep the warehouse running
If the goal is to reduce Snowflake costs, start with queries that spill to disk or remote storage, then prioritize the ones that repeat, run on larger warehouses, or sit behind pipelines and dashboards that cannot slip. The monthly bill will not name those queries. Query History will.
A faster query is the symptom of a cheaper run. Credits are the proof. Find the spills that extend warehouse runtime, reduce the intermediate data that caused them, and measure whether consumption actually fell. That is how query spillage stops being a performance curiosity and becomes a cost control.
Snowflake warehouses consume credits while they run. Query spillage slows execution by writing intermediate data to local disk or remote storage, which extends warehouse runtime and can raise credit consumption. Remote, recurring spills on larger or shared warehouses cost the most. Reduce the working set first, then match warehouse size to the job, and prove the change in credits—not only in Query Profile.
Frequently asked questions
bytes_spilled_to_local_storage and bytes_spilled_to_remote_storage, then look at execution time, frequency, and warehouse size. Prioritize remote spills that repeat on a schedule or dashboard refresh. Query Profile shows which operators produced the intermediate data.Which spilling queries are actually moving your Snowflake bill?
Take the Snowflake Cost Accountability Gap Assessment to see how well your team connects query-level waste to owners, validation, and proven credit savings.