Every Snowflake team gets hit by the same two surprises. The first is a five-figure invoice nobody expected because an auto-scaling warehouse ran hot for a week. The second is a Slack message from the VP of Sales asking why the pipeline dashboard still shows last Tuesday's numbers.
Both problems share a root cause: nobody is watching. And the usual fix -- bolt on Datadog with its Snowflake integration -- costs more than the problem it solves when all you need is a few SQL queries running on a schedule.
Here's how to monitor Snowflake costs and data freshness with SQL-native monitoring, no infrastructure agents required.
Why Datadog is overkill for Snowflake monitoring
Datadog is great at infrastructure observability. But Snowflake is not infrastructure you manage. It is a managed service with its own metadata layer -- INFORMATION_SCHEMA and ACCOUNT_USAGE -- that already tracks everything you care about: warehouse credit consumption, query history, table freshness, and schema changes.
What you actually need is something that runs SQL against those views on a schedule and alerts you when numbers cross a threshold. That is a data problem, not an infrastructure problem.
Monitor 1: Catch cost spikes before the invoice
Snowflake exposes warehouse-level credit consumption in SNOWFLAKE.ACCOUNT_USAGE.WAREHOUSE_METERING_HISTORY. This query flags any warehouse that burned more than twice its 7-day average in the last 24 hours:
WITH daily AS (
SELECT
warehouse_name,
DATE_TRUNC('day', start_time) AS usage_date,
SUM(credits_used) AS credits
FROM snowflake.account_usage.warehouse_metering_history
WHERE start_time >= DATEADD('day', -8, CURRENT_TIMESTAMP())
GROUP BY 1, 2
),
averages AS (
SELECT
warehouse_name,
AVG(CASE WHEN usage_date < CURRENT_DATE() THEN credits END) AS avg_7d,
SUM(CASE WHEN usage_date = CURRENT_DATE() THEN credits END) AS today
FROM daily
GROUP BY 1
)
SELECT warehouse_name, today, avg_7d,
ROUND(today / NULLIF(avg_7d, 0), 1) AS spike_ratio
FROM averages
WHERE today > avg_7d * 2
ORDER BY spike_ratio DESC;Run this every morning at 8 AM. If it returns rows, you have a cost spike worth investigating -- before it compounds for a month.
Fastero
Connect your database. Ask questions. Get dashboards.
Postgres, BigQuery, Snowflake, and 10+ sources — live-connected, AI-powered, no dashboard builder learning curve.
Try free →Monitor 2: Detect stale tables
A pipeline can fail silently for days. The query below checks every table in a schema against a freshness SLA. If nothing was written in the last N hours, you have stale data:
SELECT
table_schema,
table_name,
COALESCE(last_altered, created) AS last_updated,
DATEDIFF('hour', COALESCE(last_altered, created), CURRENT_TIMESTAMP()) AS hours_stale
FROM information_schema.tables
WHERE table_schema = 'ANALYTICS'
AND table_type = 'BASE TABLE'
AND DATEDIFF('hour', COALESCE(last_altered, created), CURRENT_TIMESTAMP()) > 6
ORDER BY hours_stale DESC;Six hours is a reasonable default for tables fed by hourly or daily pipelines. Adjust per table as needed. The point is: you should know about staleness before your stakeholders do.
Monitor 3: Find long-running queries killing your credits
Credit consumption is driven by query execution time. This query surfaces the worst offenders from the last 24 hours:
SELECT
query_id,
user_name,
warehouse_name,
execution_status,
total_elapsed_time / 1000 AS elapsed_seconds,
ROUND(credits_used_cloud_services, 4) AS credits,
SUBSTR(query_text, 1, 200) AS query_preview
FROM snowflake.account_usage.query_history
WHERE start_time >= DATEADD('day', -1, CURRENT_TIMESTAMP())
AND total_elapsed_time > 300000 -- over 5 minutes
ORDER BY total_elapsed_time DESC
LIMIT 20;You will almost always find a forgotten SELECT * on a multi-billion-row table or a cartesian join that someone kicked off and walked away from. Kill these patterns early and your invoice drops.
Monitor 4: Detect schema drift
When an upstream system adds, removes, or renames a column, your downstream models break. Snowflake tracks schema changes in INFORMATION_SCHEMA.COLUMNS. Compare today's schema to a baseline and you catch drift immediately:
SELECT
table_name,
column_name,
data_type,
ordinal_position,
is_nullable
FROM information_schema.columns
WHERE table_schema = 'RAW'
AND table_name = 'ORDERS'
ORDER BY ordinal_position;Store the output of this query as a snapshot. On the next run, diff against the previous snapshot. Any new column, removed column, or type change is drift that deserves a Slack alert.
For a deeper look at this pattern across warehouses, see our guide on schema drift detection.
The problem with cron + scripts
You could wire all of this up yourself: a cron job, a Python script, a Snowflake connector, and a Slack webhook. Teams do this all the time. Then the cron server gets decommissioned, or the Snowflake credentials rotate, or someone refactors the script and breaks the alert threshold, and you are back to no monitoring.
The issue is not writing the SQL. The issue is keeping the monitoring running reliably, with history, with alerting, and without maintaining yet another piece of internal tooling.
How Fastero makes this turnkey
Fastero connects natively to Snowflake and gives you four dedicated trigger types designed for exactly this kind of monitoring:
- sfStream -- triggers based on Snowflake Streams using
SYSTEM$STREAM_HAS_DATA(), so you react to actual data changes, not polling intervals. - sfCopyHistory -- monitors
COPY_HISTORYto detect when file loads succeed, fail, or stop arriving. - sfMetrics -- runs heuristic checks against
INFORMATION_SCHEMAon a schedule. This is where cost monitors, freshness monitors, and schema drift detectors live. - sfPush -- lets a Snowflake Task call an External Function that hits a Fastero webhook, so Snowflake itself pushes events to you in real time.
Each trigger can deliver alerts to Slack, email, or an arbitrary webhook. No agents to install. No YAML to maintain. Connect your Snowflake account on our Snowflake integration page and start building monitors.
Build a cost dashboard in minutes
Beyond alerting, Fastero lets you query Snowflake's ACCOUNT_USAGE views on a schedule and pipe the results into dashboard widgets. You get a living cost trend -- credits by warehouse, by day, by user -- that the whole team can see without logging into the Snowflake console.
Pair this with our cost optimization playbook and you have ongoing visibility into where your Snowflake dollars go.
Ask questions in plain English
Not everyone on the team writes SQL. Fastero's NL2SQL engine lets anyone query Snowflake metadata in natural language: "Which warehouses used the most credits last week?" or "Are there any tables in the analytics schema that haven't been updated in 3 days?" The engine translates to the right INFORMATION_SCHEMA or ACCOUNT_USAGE query, executes it, and returns the answer.
Freshness monitoring as a first-class feature
We built a dedicated data freshness monitoring solution because freshness is the single highest-signal indicator of pipeline health. Configure expected update intervals per table, and Fastero handles the rest: scheduled checks, Slack alerts with context, and a dashboard view showing every table's freshness status at a glance.
No more "when was this table last updated?" Slack threads.
Pairs well with the rest of your stack
If you are also running BigQuery, Fastero monitors both from the same platform. We covered the SQL alert pattern in depth in How to Set Up Automated SQL Alerts Without Datadog, and the data quality angle in How to Monitor Data Quality Without Monte Carlo. Schema drift detection works across warehouses too -- see How to Monitor Schema Drift in BigQuery for the BigQuery-specific version.
Get started
The SQL queries in this post work today in any Snowflake account. Copy them, run them, see what you find. When you are ready to stop babysitting cron jobs and start getting reliable alerts, Fastero runs those same queries on your schedule with triggers that just work.
Try Fastero free -- connect Snowflake, set up cost and freshness monitors in minutes, and get Slack alerts before the surprise invoice arrives. No credit card required.

