Why Snowflake Query Timeout Can Cost More Than It Saves

Blog | Snowflake Query Timeout explained

Snowflake will let a query run for two full days before it steps in to execute a query timeout. That is the default, but almost nobody knows it. 

Snowflake query timeout can be a helpful tool, depending on how you use it. Configured well, it is a circuit breaker that catches runaway logic before it burns a weekend of credits. Configured badly, you’ll pay full price for work you then throw away.

In this article, we’ll walk through what it is, how to configure it, what it costs if you get it wrong, and its overall efficacy at optimizing Snowflake costs and performance.  

What Is a Snowflake Query Timeout? 

Snowflake query timeout is a feature that sets the maximum amount of time a query is allowed to run before Snowflake automatically terminates it. It provides a safeguard against long-running queries that consume warehouse resources and drive up credit usage.

Query timeouts can help with cost control and performance management. By limiting how long a query can run, they can help prevent runaway workloads from consuming excessive compute resources. They can also prevent a single query from monopolizing warehouse capacity,  which frees up resources for other workloads and keeps performance stable.

How to Configure Snowflake Query Timeout

How Do You Check Your Current Snowflake Query Timeout Configuration? 

First, check to see what your current query timeout settings are. Most teams never do, which is how a two-day ceiling survives for years without anyone deciding on it.

SHOW PARAMETERS reports the value in force at any level. Run it at the account level to find your baseline, then at the warehouse level to see what actually governs each workload:

What Are Snowflake’s Query Timeout Parameters?

Snowflake offers two parameters for configuring query timeouts. The first stops queries that run too long, and the second stops queries that never get going. 

First,  STATEMENT_TIMEOUT_IN_SECONDS caps how long a statement may execute before Snowflake cancels it. The default is 172,800 seconds, two days, with a hard ceiling of seven

It exists because runaway queries are real: a recursive CTE with a bad join condition loops until something stops it, and a cross join nobody intended will scan happily until Monday. Every account needs this circuit breaker. Unfortunately, however, most accounts haven’t given much thought to where it is set.

Its sibling is better hidden and arguably more interesting. STATEMENT_QUEUED_TIMEOUT_IN_SECONDS caps how long a statement may wait in the warehouse queue before being canceled, and its default is zero: no limit at all. By default, a query can queue forever, silently, on a warehouse that bills for every second it runs. 

Setting a queued timeout on a latency-sensitive warehouse does something subtle and valuable: it converts invisible waiting into a visible error you can alert on. A query that fails fast with a queue timeout is a signal. A query that waits nine minutes and then succeeds is a cost nobody files a ticket about.

How Do You Alter Your Snowflake Query Timeout Configuration?

Both parameters can be set at the account, user, session, and warehouse level. You can make these adjustments with a simple SQL command:

ALTER ACCOUNT   SET STATEMENT_TIMEOUT_IN_SECONDS = 14400; ALTER WAREHOUSE bi_wh SET STATEMENT_TIMEOUT_IN_SECONDS = 600; ALTER USER      etl_svc SET STATEMENT_TIMEOUT_IN_SECONDS = 21600; ALTER SESSION   SET STATEMENT_TIMEOUT_IN_SECONDS = 3600; 

Within the session hierarchy, the more specific level wins: session beats user, user beats account. But when a warehouse and a session both have the parameter set, the lower value is enforced. That rule surprises people, and it is the one worth designing around. A generous session setting cannot buy a query more time than its warehouse allows, which makes the warehouse the natural home for policy and the session the place for deliberate exceptions.

What Is a Good Snowflake Query Timeout Setting?

Ultimately, there’s no hard and fast rule for how long a Snowflake query timeout setting should run. It depends entirely on the workload. For example: 

  • A BI warehouse serving humans has no business running a query for an hour. If a query runs for longer than ten minutes, that’s a sign to stop, diagnose the problem, and fix it. 
  • A warehouse that owns nightly workloads runs long by design. Set its ceiling near the median and you will cancel your own pipeline for the crime of operating normally.

Set the number above the legitimate maximum, place it on the warehouse where policy belongs, and reserve the session for deliberate exceptions. A timeout tuned this way will run quietly in the background until a genuine problem arises. 

How Much Does a Dead Snowflake Query Cost You? 

Snowflake bills per second of execution, and a canceled query is billed for every second it ran before cancellation. Which means that if you run a 50-minute query that gets timed out at the 45-minute mark, you pay for each of those 45 minutes with nothing to show for it. 

In other words, a tight query timeout on necessary work does not cap costs. It multiplies them, and makes the pipeline late as a bonus.

There is actual theory on when killing and restarting a computation pays off. Researchers Michael Luby, Alistair Sinclair, and David Zuckerman formalized optimal restart strategies in 1993. They advocated restarting wins when run times are highly unpredictable, so a fresh start has a real chance of finishing sooner than the run you abandoned. 

A deterministic SQL load is the opposite case. The retry takes roughly the same time the original was going to take. Killing it and rerunning is not a strategy. It’s the same forty-five minutes, purchased in a loop, by a policy that cannot tell an exploding join from a quarterly aggregation that simply has a quarter of data to read.

What to Do When A Query Timeout Fires 

When a timeout fires, the error message reads “Statement reached its statement or warehouse timeout.” Confirm that text first, because client-side disconnects masquerade as timeouts and send people down the wrong road. Then pull the following query: 

SELECT query_id, user_name, warehouse_name, warehouse_size,   ROUND(execution_time / 1000, 0) AS seconds_billed_before_cancel,   error_message FROM snowflake.account_usage.query_history WHERE error_message ILIKE '%statement reached its statement or warehouse timeout%'   AND start_time > dateadd('days', -30, current_date) ORDER BY execution_time DESC; 

That middle column is exactly what it sounds like: compute you paid for and then discarded. Each row deserves a why. Typical causes include:

  • A warehouse short on memory and spilling to storage
  • Awarehouse oversubscribed on concurrency so the clock ran out in the queue
  • A join multiplying rows it should not
  • Pruning so poor the query read the whole table to answer for a week

Notice what all four have in common: the timeout caused none of them. This is typical: the timeout is the fire alarm, not the cause of the fire itself.  You can reset the alarm all day, but that’s not going to put out the fire. 

The fix, in every case, is fit: the memory the query needed, the isolation the crowd needed, or the rewrite of the join needed. 

This is what my team at Keebo works on: keeping warehouses continuously matched to their workloads, inside SLA guardrails you define, so the slow query that keeps kissing the ceiling gets what it needs instead of an execution date. In a well-fitted warehouse, the timeout goes back to being what it was meant to be. The alarm that almost never rings.

Frequently Asked Questions

What Is the Difference Between Statement Timeout and Queued Timeout?

STATEMENT_TIMEOUT_IN_SECONDS caps execution time. STATEMENT_QUEUED_TIMEOUT_IN_SECONDS caps time waiting in the warehouse queue, and it defaults to unlimited.

How Do I Set a Timeout for Snowflake Tasks?

Tasks answer to a different parameter. USER_TASK_TIMEOUT_MS caps how long a scheduled task may run before Snowflake cancels it, and the value is in milliseconds, not seconds. The default is one hour, which is far tighter than the two-day statement default, but it is still worth a look, since a task that hangs on a bad dependency will bill for the full hour before it stops. Set it the way you would a statement timeout: above the task’s legitimate runtime, so it fires only for pathology. To change it, run ALTER TASK my_task SET USER_TASK_TIMEOUT_MS = 1800000; for a thirty-minute ceiling.

Do Timeouts Replace Resource Monitors?

No, and the two are not the same tool. A timeout governs a single statement or task and cancels it when it runs too long. A resource monitor governs credit consumption across a warehouse or account and can notify you, or suspend the warehouse, when spend crosses a threshold you set. The timeout is the circuit breaker on one query. The resource monitor is the spend cap on the whole warehouse. Use both: the timeout catches the runaway query in the moment, and the resource monitor catches the slow accumulation of cost that no single query would ever trip.

How Do I Get Alerted When a Query Times Out?

The diagnostic query above tells you what already happened, but you can make it tell you in real time. Snowflake alerts can run that same QUERY_HISTORY check on a schedule and send an email through a notification integration whenever a timeout appears in the last interval. The setup is three pieces: a notification integration for the email channel, an alert that runs the check on a schedule, and the recipient list. Point it at the warehouses that matter and you convert a silent cancellation into a signal someone actually sees. A timeout nobody notices is a cost nobody fixes.