All articles
Diagnostics·6 min read

How much of your Snowflake bill is agent-shaped?

A copy-pasteable SQL diagnostic against QUERY_HISTORY that tells you, in one number, how much of your Snowflake spend is the kind no amount of warehouse tuning will fix.

MT
Melt TeamBuilders of Melt · May 16, 2026

"Agent-shaped" is a phrase we've been using a lot. It refers to a specific traffic pattern that started showing up on Snowflake bills in late 2025: thousands of small, repetitive, single-table reads emitted by an LLM-driven agent fleet as it iterates toward an answer. Each query is fine. The aggregate is what bends the bill curve.

Most cost playbooks won't catch this pattern, because the playbooks were written for human-driven workloads. The traffic doesn't look like a runaway query, a misconfigured warehouse, or a forgotten schedule. It looks like a lot of perfectly reasonable queries that are individually cheap.

This post is one query you can paste into a worksheet to find out how much of your bill is agent-shaped. No tools, no signup, no install. Just SQL against SNOWFLAKE.ACCOUNT_USAGE.QUERY_HISTORY.

What "agent-shaped" actually means

Working definition, derived from going through real agent-fleet bills query by query:

  • Small. Bytes scanned under 200 MB. Big enough to be a real query, small enough that DuckDB on a single box would answer it in milliseconds.
  • Fast. Total elapsed time under 5 seconds. Even on the smallest Snowflake warehouse, a query under 5 seconds is dominated by spin-up overhead.
  • Read-only. SELECT only. Writes are a different cost category.
  • Simple. Most are filters, counts, group-bys, or top-N. We don't gate on this directly because QUERY_HISTORY doesn't expose join counts, but the bytes/latency filter does most of the work.

Those four properties together describe the workload an LLM agent produces while it's iterating on a prompt. They also describe a workload DuckDB can answer for cents.

The diagnostic

Run this in any Snowflake worksheet with access to ACCOUNT_USAGE. It covers the last 30 days and is safe to run on production:

with classified as (
  select
    query_id,
    user_name,
    warehouse_size,
    total_elapsed_time / 1000.0                   as elapsed_seconds,
    bytes_scanned,
    case warehouse_size
      when 'X-Small'  then 1
      when 'Small'    then 2
      when 'Medium'   then 4
      when 'Large'    then 8
      when 'X-Large'  then 16
      when '2X-Large' then 32
      when '3X-Large' then 64
      when '4X-Large' then 128
      else 1
    end                                           as credits_per_hour,
    case
      when bytes_scanned     < 200 * 1024 * 1024
       and total_elapsed_time < 5000
       and query_type         = 'SELECT'
      then 1 else 0
    end                                           as is_agent_shaped
  from snowflake.account_usage.query_history
  where start_time >= dateadd(day, -30, current_timestamp())
    and warehouse_size is not null
    and execution_status = 'SUCCESS'
)
select
  count(*)                                                                 as total_queries,
  sum(is_agent_shaped)                                                     as agent_queries,
  round(100.0 * sum(is_agent_shaped) / nullif(count(*), 0), 1)             as agent_query_pct,

  round(sum(elapsed_seconds * credits_per_hour) / 3600 * 3, 2)             as total_cost_usd,
  round(sum(case when is_agent_shaped = 1
                  then elapsed_seconds * credits_per_hour
                  else 0 end) / 3600 * 3, 2)                               as agent_cost_usd,
  round(100.0 * sum(case when is_agent_shaped = 1
                          then elapsed_seconds * credits_per_hour
                          else 0 end)
              / nullif(sum(elapsed_seconds * credits_per_hour), 0), 1)     as agent_cost_pct
from classified;

The query returns one row with six numbers. The two that matter are agent_query_pct (how much of your traffic looks agent-shaped) and agent_cost_pct (how much of your bill that traffic accounts for).

How to read the result

Some guideposts from real accounts:

  • Under 15%. You have a mostly human-driven workload. The standard cost playbook (auto-suspend, warehouse right-sizing, refresh cadence) is still where your wins are. The field guide here covers it.
  • 15–40%. An agent fleet is starting to bend your bill, but it's not yet dominant. Manual tuning still helps. This is the band to monitor; the curve compounds quickly.
  • 40–70%. Agent-shaped traffic is now the main driver of your bill. Warehouse-sizing changes can't move it much, because the queries are short enough that they're dominated by the per-minute spin-up floor.
  • Over 70%. Your bill is being driven by traffic that shouldn't have been on Snowflake in the first place. The fix is routing those queries to a cheaper engine, not tuning the warehouse they land on.

The math: an agent-shaped query against a synced Iceberg or DuckLake table costs effectively nothing on DuckDB. The same query on Snowflake costs you a minute of warm warehouse credits at the size you've provisioned. No warehouse-sizing change closes that gap.

Want the breakdown by user?

Drop this in after running the query above to see which user or service account is producing the agent-shaped traffic. In every account we've reviewed, the answer concentrates on one or two service users.

with classified as (
  select
    user_name,
    total_elapsed_time / 1000.0 as elapsed_seconds,
    case warehouse_size
      when 'X-Small'  then 1
      when 'Small'    then 2
      when 'Medium'   then 4
      when 'Large'    then 8
      when 'X-Large'  then 16
      when '2X-Large' then 32
      else 1
    end as credits_per_hour,
    case
      when bytes_scanned     < 200 * 1024 * 1024
       and total_elapsed_time < 5000
       and query_type         = 'SELECT'
      then 1 else 0
    end as is_agent_shaped
  from snowflake.account_usage.query_history
  where start_time >= dateadd(day, -30, current_timestamp())
    and execution_status = 'SUCCESS'
    and warehouse_size is not null
)
select
  user_name,
  sum(is_agent_shaped)                                                  as agent_queries,
  round(sum(case when is_agent_shaped = 1
                  then elapsed_seconds * credits_per_hour
                  else 0 end) / 3600 * 3, 2)                            as agent_cost_usd
from classified
group by 1
having sum(is_agent_shaped) > 0
order by agent_cost_usd desc
limit 20;

Caveats worth knowing

  • The cost formula is an approximation. It assumes the query has a warehouse to itself for total_elapsed_time, which is wrong in the direction of overstating cost on busy warehouses (concurrent queries share the warehouse) and understating it on bursty ones (each spin-up pays the 60-second minimum). For an order-of-magnitude diagnostic, it's good enough. For an audit, use QUERY_ATTRIBUTION_HISTORY.
  • The thresholds are heuristics. 200 MB and 5 seconds are conservative defaults from our agent-fleet bench harness. If your workload is different, adjust them. If most of your "small" queries are actually 50 MB and 1 second, tighten the filter and the numbers will land where you expect.
  • It only sees what reached Snowflake. If you already cache aggressively in the application layer, the diagnostic won't see what didn't run. That's fine. The question we're answering is how much of what did run was agent-shaped.

What to do with the number

If agent_cost_pct came back under 25%, your wins are still in the standard playbook. Field guide here.

If it came back over 40%, plug the same workload numbers into the cost calculator with a high lake-eligible fraction. The math is detailed there. For agent-shaped traffic against synced tables, expect savings in the 75–97% range. That's the range we see on our design partners' bills.

If it came back over 70%, talk to us. The repo is open, the proxy is self-hosted, and the migration is one connection-string change.

Melt Team