A Snowflake query that normally finishes in seconds suddenly takes minutes. The warehouse is running, nothing has failed, and the SQL may even look perfectly reasonable. Then someone opens Query Profile and finds the clue: bytes spilled to local storage—or worse, remote storage.

At that point the technical diagnosis seems straightforward. Snowflake ran out of sufficient memory for an operation, intermediate data moved out of memory, and query performance suffered. Snowflake itself recommends investigating the operators responsible and considering remedies such as using a larger warehouse or processing data in smaller batches.

Detecting spillage is not the same as resolving it. A larger warehouse might help. A query rewrite might be better. The workload might be competing with queries that should never have shared the same warehouse. An exploding join may be generating far more intermediate data than intended. Or the spill may be an occasional exception that does not justify permanently increasing warehouse capacity. The difficult work begins after the metric appears: who owns the problem, which intervention is justified, how to prove it worked, and how to keep the pattern from returning. That is where query spillage stops being only a performance-tuning problem and becomes a workload governance problem.

What Snowflake query spillage actually means

Snowflake virtual warehouses provide the compute used to execute queries. Some operations require substantial working memory, particularly when queries create large intermediate results through joins, sorting, aggregation, duplicate elimination, or other data-intensive processing. When an operation cannot fit within the memory available to the warehouse, Snowflake can spill intermediate data to local disk. If additional capacity is required beyond that, data can spill to remote cloud storage. Snowflake notes that both affect performance, with remote storage generally producing the more severe degradation. Because warehouses consume credits while they run, that extra elapsed time is also a cost event; the credit mechanism is covered in How Query Spillage Increases Snowflake Costs.

This behavior is relatively observable. Snowflake exposes it through Query History using metrics including bytes_spilled_to_local_storage and bytes_spilled_to_remote_storage. Query Profile can then identify which operators in the execution plan contributed to the problem. Performance Explorer adds a warehouse-level view, including the percentage of queries with spilled bytes and spilled bytes relative to bytes read. A platform team can therefore identify which queries spilled, which warehouse executed them, how much data spilled, and whether remote storage was involved.

Those metrics describe what happened. They do not necessarily tell the organization what it should do next. A 200 GB remote spill on a nightly transformation is a different operational problem from a one-off analyst query that spilled because a join key was wrong. The same column in Query History can represent an under-provisioned warehouse, a defective query, a concurrency collision, or a workload that should never have been on that warehouse at all. Observability gets you to the symptom. It does not select the intervention.

Why Snowflake queries spill

The obvious explanation for spillage is that a query required more memory than its warehouse could provide. That is technically correct and operationally incomplete.

Consider a query performing a very large aggregation. Increasing the warehouse size might provide enough memory to execute the operation without spilling, and Snowflake explicitly recommends considering a larger warehouse when addressing memory spillage. Now consider another query spilling because a poorly constructed join generates dramatically more rows than its inputs. Query Insights can identify exploding joins, unnecessary aggregation, unnecessary UNION DISTINCT, remote spillage, and other patterns that contribute to inefficient execution. Giving that second query more resources may improve its runtime without addressing the underlying query behavior. The spill disappears; the waste remains, only now it is more expensive.

Concurrency introduces another variable. A warehouse does not execute every query in isolation, and limiting concurrently running queries is among the strategies Snowflake includes when teams investigate warehouse performance. Workload architecture matters too. Optimization is more straightforward when a warehouse runs similar work; when substantially different queries share the same warehouse, a performance enhancement can be wasted on workloads that do not benefit from it.

So the observation that a query spilled 200 GB to remote storage does not automatically produce the conclusion that the warehouse should be increased. It produces an investigation.

Why resizing the warehouse is not a governance strategy

Warehouse resizing is useful precisely because Snowflake makes compute elastic. When a workload genuinely requires additional memory, increasing warehouse size can be the correct response. Larger warehouses also provide more compute and consume credits at correspondingly higher rates. Snowflake cautions that larger is not necessarily faster for every workload and that warehouse sizing should reflect the queries being executed.

That creates a trade-off a spillage metric cannot resolve on its own. Suppose a recurring query spills on a Medium warehouse. Moving it to Large may eliminate the spill and improve runtime. Before making that change permanent, an engineering team still needs workload context: whether the job is inherently memory intensive, whether data volume has grown, whether inefficient SQL is producing unnecessary intermediate data, whether concurrency has changed, whether the workload should have its own warehouse, whether the query can be processed in smaller batches, and whether faster execution is important enough to justify the additional compute. Warehouse right-sizing only holds when those questions have answers.

These are not questions bytes_spilled_to_remote_storage can answer. They require ownership, business priority, and an understanding of what else runs on the same warehouse. That is where many Snowflake optimization programs begin to struggle. The metric is clear. The decision is not.

What to do after the spill is detected

Imagine monitoring identifies this pattern: warehouse RETAIL_WH, a recurring transformation, significant remote spillage, dozens of executions per day, and increasing runtime. The technical signal is clear. What happens next is usually where the process stalls.

Someone needs to determine which application, pipeline, or dashboard is generating the query, then establish who owns that workload. In an environment with shared warehouses, service accounts, and scheduled jobs, that is rarely trivial. The person who discovers the spill may not own the SQL, and the original author may have moved teams. The problem is visible, but nobody clearly owns its resolution. That is the gap between monitoring and governance.

The first step is therefore not prescribing a fix. It is tracing the behavior back to its operational source: which query caused it, which warehouse executed it, how frequently the pattern occurs, which workload generates the query, who owns that workload, and whether the behavior appeared suddenly or grew with data volume. Snowflake already exposes much of the technical evidence through Query History, Query Profile, Query Insights, and operator statistics. The governance challenge is connecting those signals to engineering context.

A single spill may not matter. A query spilling every fifteen minutes probably deserves different treatment. An occasional month-end workload may legitimately require additional capacity, while a recurring transformation that spills because of an exploding join is an optimization opportunity. The objective is not to eliminate every nonzero spillage metric. Snowflake notes that Query Acceleration Service can produce a small amount of remote-storage writing even when QAS is not ultimately used. The objective is to understand which behavior matters enough to act on.

Once the workload has been traced, assignment has to become explicit. Platform teams manage warehouses, data engineering owns transformations, analytics owns dashboards, and FinOps monitors consumption, so a spillage alert sent to everyone can become an alert owned by nobody. The assigned owner does not have to perform every change. They do have to decide whether the right response is query optimization, warehouse configuration, workload routing, concurrency management, batching, or accepting the current behavior.

The intervention then has to be proven rather than assumed. Did remote spillage disappear? Did execution time improve? Did warehouse consumption increase or decrease? Did the change affect concurrency for other workloads, or simply move the problem somewhere else? A merged pull request is not necessarily an optimization. A warehouse resize is not automatically an improvement. The outcome needs evidence.

Enforcement is the step most programs skip. The query was fixed, spillage disappeared, and the incident closed. Six months later, data volumes have doubled, a new engineer modifies the transformation, or another workload is routed onto the same warehouse. Nothing necessarily failed. The environment evolved, and the original problem returned. A resolved optimization should become a governed behavior. Otherwise the organization repeatedly pays engineers to rediscover the same class of problems.

In practice, that loop looks like this:

  • Trace the spill to the query, warehouse, frequency, workload, and owner.
  • Assign the issue to someone who can decide among rewrite, resize, reroute, batch, or accept.
  • Prove the intervention with before-and-after spillage, runtime, concurrency, and credit evidence.
  • Enforce the resulting behavior so the same pattern does not quietly return.

From query tuning to workload governance

Spillage is useful because it illustrates a broader problem with cloud cost optimization. Modern platforms are very good at generating signals. Snowflake can tell teams about query behavior, execution time, warehouse activity, queueing, spilling, and other performance characteristics. The technical visibility available to engineering teams continues to improve. Visibility does not automatically produce action.

Between a detected problem and a measurable outcome sits an operational workflow: Trace → Assign → Prove → Enforce. That workflow applies to far more than query spillage. Repeated expensive queries follow the same pattern. Oversized or poorly utilized warehouses follow the same pattern. Unused storage follows the same pattern. AI and Cortex workloads will increasingly follow the same pattern. The optimization category may change; the governance problem remains remarkably consistent.

If query spillage matters in your environment, bytes_spilled_to_remote_storage is an important metric, but it should not be the end of the measurement model. Teams should also understand whether spilling workloads are recurring, which warehouses and workloads are responsible, whether ownership has been established, whether remediation has been assigned, how long issues remain unresolved, what intervention was performed, what changed afterward, and whether the same behavior eventually returned. Governance adds another layer: what percentage of meaningful optimization issues actually reach closure? That may ultimately be more valuable than knowing how many issues were detected.

This is the operating difference Anavsan is built around. Native Snowflake telemetry can show that a query spilled. Workload governance has to connect that spill to an owner, drive a decision, evidence the outcome, and keep the fix from drifting away as the platform changes. Detection is observability. Resolution requires accountability.

Detection is observability. Resolution requires accountability.

Snowflake query spillage is a technical performance problem, and there are established technical approaches for diagnosing and addressing it. At scale, technical diagnosis is only part of the challenge. Someone has to determine whether the spill matters, understand the workload behind it, choose the appropriate intervention, implement it, and produce evidence that the change improved the outcome. Then the organization needs a way to prevent the same waste from quietly returning.

The next time Query Profile shows significant remote spillage, the useful test is not only whether the query can be made faster. It is whether the team can trace it, assign it, prove the fix, and keep it fixed. That is a much better measure of whether Snowflake optimization is actually working.

TL;DR

Snowflake query spillage occurs when operations exceed available warehouse memory and intermediate data spills to local disk or remote storage, which can significantly hurt performance. Detecting the spill, however, does not determine the right intervention. Mature teams connect technical evidence to workload ownership and follow the issue through Trace → Assign → Prove → Enforce, turning performance findings into governed, measurable outcomes.

Frequently asked questions

Snowflake query spillage occurs when an operation needs more working memory than the virtual warehouse can provide. Snowflake then writes intermediate data to local disk, and if that is still not enough, to remote cloud storage. Both slow execution; remote spillage is usually the more severe degradation.
Local spillage writes intermediate data to disk attached to the warehouse. Remote spillage writes beyond that to cloud storage. Remote spillage is typically slower because data has to move through remote storage, and it is often a stronger signal that the query, warehouse size, concurrency, or workload placement needs attention.
No. A larger warehouse can be the right response for a genuinely memory-intensive workload, but it is not a governance strategy. The same spill can come from an exploding join, mixed workloads on a shared warehouse, concurrency pressure, or data growth. Resizing without that context can raise credit consumption without fixing the underlying query behavior.
Query History exposes bytes_spilled_to_local_storage and bytes_spilled_to_remote_storage. Query Profile identifies which operators contributed. Performance Explorer adds warehouse-level measures such as the percentage of queries with spilled bytes and spilled bytes relative to bytes read. Query Insights can surface related patterns such as exploding joins and unnecessary aggregation.
Detection tells you that an operation exceeded available memory. It does not tell you which workload produced the query, who owns it, whether the spill is recurring, which intervention is justified, whether the change actually improved runtime or credits, or whether the same pattern will return as data volumes and routing change.
Trace connects the spill to a query, warehouse, frequency, workload, and owner. Assign puts a named person in charge of deciding among rewrite, resize, reroute, batch, or accept. Prove compares spillage, runtime, concurrency, and credits before and after the change. Enforce keeps the resulting behavior from drifting back as the environment evolves.
No. A single spill or a legitimate month-end workload may not deserve a permanent warehouse increase. Snowflake also notes that Query Acceleration Service can produce a small amount of remote-storage writing even when QAS is not ultimately used. The objective is to act on behavior that is recurring, material, and owned—not to drive every nonzero metric to zero.

How well does your team move from Snowflake findings to enforced fixes?

Take the Snowflake Workload Governance & Enforcement Health Assessment to evaluate visibility, ownership, validation, drift readiness, and enforcement across your environment.

Continue reading