< blog
9 min read

Snowflake Auto-Clustering Costs Out of Control? How to Find the Tables Driving Them and What to Do

Illustration of a grid of table partitions with a few highlighted ones drawn together into a cluster, beside a stack of gold coins

TL;DR

  • Automatic Clustering bills as its own service. It does not show up under a warehouse, so you will not find it by looking at warehouse credits.
  • Since 1 September 2026, newly clustered tables use Optima Clustering, which is billed by data ingested rather than compute time. Tables that were already clustered stay on Clustering Classic. Your bill can contain both.
  • Find the cost per table first, split by version. A handful of tables usually carries it.
  • Then ask the question Snowflake’s own guidance asks: do queries on this table prune well, and does the table change much less often than it is read?
  • Fix, pause or drop. Dropping the clustering key is the only option that ends the cost for good.

What changed on 1 September 2026

Snowflake now has two versions of Automatic Clustering, and both bill under the same Auto Clustering service type.

Clustering Classic Optima Clustering
Which tables Tables that were already clustered Tables clustered for the first time from 1 September 2026
How it is billed Serverless compute credits: the initial clustering, then more as DML changes the table Uncompressed GB ingested times the per-GB rate times an overlap factor between 0 and 1
What that means Cost follows how much the table changes Well-clustered incoming data has an overlap factor near 0, so its cost is near zero; data that needs full clustering is billed at the full rate

Snowflake documents that you do not need to take any action for the rollout, that changing a clustering key does not move a table to Optima, and that there is no command to migrate. The overlap factor does not appear as a line on your bill. Rates for both versions are in Snowflake’s Service Consumption Table.

Step 1: find the tables behind the bill

AUTOMATIC_CLUSTERING_HISTORY shows credits per table, and its VERSION column says whether the credits came from CLASSIC or OPTIMA.

select database_name,
schema_name,
table_name,
version,
round(sum(credits_used), 2) as credits,
round(sum(num_bytes_reclustered) / power(1024, 4), 2) as tb_reclustered
from snowflake.account_usage.automatic_clustering_history
where start_time >= dateadd(day, -30, current_timestamp())
group by database_name, schema_name, table_name, version
order by credits desc
limit 25;

Two things to know. A row can be reclustered more than once, so the rows or bytes reclustered can exceed the size of the table. That can happen on a table that changes a lot, and it is not an error. And the view’s latency is up to three hours.

Resource monitors cannot cap this spend: Snowflake documents that they cannot limit credit use for the automatic clustering service. Cost control here is done table by table.

Step 2: ask whether clustering still pays

Snowflake’s guidance for clustering keys is specific. Clustering suits tables with a large number of micro-partitions, typically multiple terabytes, where queries are selective, a high percentage of the queries can use the same keys, and the table has a high query-to-DML ratio. Snowflake also warns that keys are not intended for all tables because of the cost of clustering, and recommends at most 3 or 4 columns per key for most tables, because more than that tends to increase cost more than benefit.

Test those conditions on each of the top tables from Step 1. Replace the table name.

Do queries prune well? Compare partitions scanned with partitions in total for queries that read the table. A value near 1 means queries read almost everything, so clustering is not helping them.

with reads as (
select ah.query_id
from snowflake.account_usage.access_history ah,
lateral flatten(input => ah.base_objects_accessed) f
where ah.query_start_time >= dateadd(day, -30, current_timestamp())
and f.value:objectName::string = 'MY_DB.MY_SCHEMA.MY_TABLE'
)
select count(*) as queries,
round(avg(qh.partitions_scanned / nullif(qh.partitions_total, 0)), 3) as avg_share_of_partitions_scanned
from reads r
join snowflake.account_usage.query_history qh
on qh.query_id = r.query_id
where qh.partitions_total > 0;

PARTITIONS_TOTAL counts micro-partitions across all tables in a query, so a query that joins several tables blurs the ratio. If most of the queries are joins, treat the number as a hint and look at a few queries by hand. ACCESS_HISTORY requires Enterprise Edition or higher.

How often does the table change compared with how often it is read? Count the write statements in the same window.

select count(distinct ah.query_id) as write_queries
from snowflake.account_usage.access_history ah,
lateral flatten(input => ah.objects_modified) f
where ah.query_start_time >= dateadd(day, -30, current_timestamp())
and f.value:objectName::string = 'MY_DB.MY_SCHEMA.MY_TABLE';

Compare it with the queries figure above. Many reads per write is what clustering is built for. A table that is written to constantly and read rarely is the classic runaway: you pay to recluster data that changes again before anyone benefits. Snowflake suggests grouping DML into larger, less frequent batches if a heavily updated table must be clustered.

What is the key?

show tables like 'MY_TABLE' in schema MY_DB.MY_SCHEMA;

Look at cluster_by and automatic_clustering. A key with more than three or four columns, or one built on a column your queries do not filter on, is a candidate to simplify.

Step 3: decide

What you found Do this
Queries prune well, reads far outnumber writes, cost is steady Keep it. The cost is buying something.
The key has too many columns, or does not match how people filter Redesign the key. Changing a key resumes Automatic Clustering, so plan for reclustering work and credits afterwards.
Almost no pruning benefit, or heavy writes and few reads Drop the key.
You need the bill to stop now and will decide later Suspend, with care. See below.

The commands:

alter table my_db.my_schema.my_table suspend recluster;
alter table my_db.my_schema.my_table resume recluster;
alter table my_db.my_schema.my_table drop clustering key;

How each option behaves, according to Snowflake’s documentation:

  • Suspend stops reclustering and the related credits on a Classic table. Resuming can trigger reclustering if the table has drifted.
  • Under Optima, suspending stops billing for newly ingested data, but resuming applies a catch-up cost for what arrived while it was suspended. Snowflake says that suspending mainly to save money is generally not cost-effective for Optima tables.
  • Drop clustering key ends the clustering cost permanently. After the drop, the table shows automatic_clustering as OFF.
  • Cloned tables start with Automatic Clustering suspended, so a clone of a clustered table does not start accruing cost until someone resumes it.

Dropping a key does not delete data or change query results. Queries that depended on the clustering may scan more. Check the slowest queries on the table afterwards.

Step 4: check it worked

Re-run Step 1 a week after the change, for the same tables, and compare credits per day. Then look at the queries that used the table: if their run time and bytes scanned are close to what they were, the clustering was not earning its cost.

To see which version a table uses, call SYSTEM$CLUSTERING_INFORMATION on it, or use the VERSION column from Step 1. SHOW TABLES and the TABLES view show whether clustering is on, and the key.

How Seemore handles this

Seemore Data’s Auto-Clustering feature runs an efficiency audit of your existing clustered tables and looks for new clustering opportunities. In Seemore’s documentation, the Auto-Clustering Agent analyses your tables with auto-clustering turned on, looks at whether keys match real query filters, how often each table is queried and how often it changes, and recommends whether to optimize, keep or disable clustering with an estimated cost impact and the SQL to apply it. The Remove Auto-Clustering insight flags tables where auto-clustering costs more than it benefits and recommends dropping the key. Both only recommend: you run the SQL in Snowflake. For the reasoning behind it, see Intelligent Snowflake Auto Clustering: How to Optimize Auto-Clustering at Scale with AI.

Frequently asked questions

Why is auto-clustering not on my warehouse bill?

It runs in the background without a warehouse you choose, and Snowflake bills it under the Auto Clustering service type. Look at AUTOMATIC_CLUSTERING_HISTORY, or at METERING_DAILY_HISTORY with SERVICE_TYPE = 'AUTO_CLUSTERING'.

Does Optima Clustering make clustering cheaper?

Snowflake describes the billing as predictable, based on the uncompressed data ingested rather than compute time, and says the cost for well-clustered incoming data is near zero. Whether your total goes down depends on your tables. Compare the OPTIMA and CLASSIC rows in Step 1 once you have some of each.

Can I stop auto-clustering without losing the clustering key?

On a Classic table, suspending reclustering stops the related credits while keeping the key. On an Optima table suspending is generally not cost-effective, because resuming applies a catch-up cost. If you want the cost to end, drop the key.

Which tables should be clustered at all?

According to Snowflake: large tables with many micro-partitions, typically multiple terabytes, queried with selective filters that share the same keys, and changed much less often than they are read.

Does changing a clustering key reset anything?

Changing the key resumes Automatic Clustering on the table, even if the column is unchanged when you include LINEAR. Expect reclustering work, and credits, after a redesign.