SNOWFLAKE DATA METRIC FUNCTIONS
Snowflake Data Metric Functions (DMFs): Schedule, Cost, Limits and Data Quality Monitoring
Freshness, volume, schema and distribution monitoring across every table in your Snowflake account, on any edition, with baselines learned per table instead of thresholds typed per table. Read only connection, alerts in Slack and PagerDuty, from 99 dollars a month.
14-day trial, no credit card, read-only connection
Alerted #data-eng 0.8s ago.
Downstream impact · consumers at risk
What do Snowflake data metric functions cost to run?
Data metric functions bill as the Data Quality Monitoring serverless feature: one Platform Credit per compute-hour multiplied by two, plus cloud services at one. ROW_COUNT is the single documented exception at 0.9. The identical SQL run as a serverless task carries a 0.9 multiplier, so the native quality feature costs more than the equivalent task.
Last updated August 2026
Side by side
Snowflake data metric functions compared
Swipe to see all columns →
| Data metric function or alternative | What it measures | Compute multiplier | Documented limits and notes |
|---|---|---|---|
| SNOWFLAKE.CORE.ROW_COUNT | How many records are in the table or view | 0.9 (Snowflake Service Consumption Table, August 2026) | The one documented carve out. Footnote 12 of the Serverless Feature Table states that the ROW_COUNT DMF uses a Snowflake-managed compute multiplier of 0.9, where the rest of Data Quality Monitoring bills at 2 |
| SNOWFLAKE.CORE.FRESHNESS | Seconds elapsed since the table was last modified, or since the newest value in a timestamp column you nominate | 2 | Enterprise Edition only. The column argument is optional for a table and required for a view or an external table. Any write moves the clock, so a backfill or a metadata operation reads as fresh |
| Accuracy DMFs such as NULL_COUNT, BLANK_COUNT, DUPLICATE_COUNT and UNIQUE_COUNT | Rule breaks on a column you name, returned as a count or a percentage | 2 | Enterprise Edition only. Each association of one function to one object counts against the account ceiling of 50,000 associations |
| SNOWFLAKE.CORE.SCHEMA_CHANGE_COUNT | Columns added, dropped, renamed or retyped since the previous evaluation | 2 | Enterprise Edition only. It counts the changes, it does not tell you which downstream model or dashboard breaks because of them |
| A custom data metric function | Whatever your SQL expresses, for the business rules the system metrics do not cover | 2 | Billed under the same Data Quality Monitoring feature. You own the SQL, the tests for the SQL, and the version control around it |
| The same check written as a serverless task | Whatever your SQL expresses | 0.9 | Serverless Tasks carry a 0.9 multiplier and Serverless Tasks Flex 0.5, so identical logic outside Data Quality Monitoring bills at a fraction of the DMF rate. You give up the results view and the Snowsight surface |
| Dataobservability | Freshness, volume, schema and distribution across every table, scored against a baseline learned per table | Not metered on Snowflake credits | Runs on our compute against a read only role, so widening coverage does not add warehouse spend. Snowflake, BigQuery, Databricks and Redshift. From 99 dollars a month, 14 day trial, no card |
Positioning and pricing models are summarized in good faith from each vendor's public pages, August 2026. Verify current terms with the vendor.
What you get
What a monitoring layer adds on top of Snowflake data metric functions
Coverage by inventory instead of coverage by association
The data metric function model is one association at a time: you attach a function to an object, and that object is monitored. It is exact, and it is a project. Somebody has to decide which of the several thousand tables in the account deserve a check, write the association, pick the threshold, and repeat that work every time a pipeline adds a table. The account level ceiling of 50,000 total associations is generous, but the real ceiling is attention. Metadata driven monitoring inverts the default: the table list is the input, so a table added on Tuesday is watched on Tuesday without anyone filing a ticket.
A threshold that knows Tuesday is not Sunday
A freshness check written as a fixed number of hours is wrong twice a week for most tables. A table loaded hourly on business days and never at the weekend is not stale on Saturday morning, and a table that loads at 02:00 on the first of the month is not stale on the third. Fixed thresholds cannot encode that, so teams either set them loose enough to miss real incidents or tight enough to page someone about the calendar. Baselines derived from each table observed load pattern get seasonality for free, which is the difference between an alert people read and an alert people filter.
Alerts that reach the person on call, not just Snowflake users
Snowflake native data quality notifications run through a notification integration, and the email path carries a constraint worth reading twice: you can send email notifications only to Snowflake users within the same account, and each address in ALLOWED_RECIPIENTS has to be verified. That rules out a shared on call alias, a PagerDuty inbound address, or the analytics lead who does not hold a Snowflake seat. Routing to Slack and PagerDuty from the start removes an integration project that otherwise sits between detection and response.
Detection frequency that is not a billing decision
Because Data Quality Monitoring bills per evaluation at a 2x multiplier, the schedule you choose is also a budget you choose. Moving a table from the default hourly evaluation to the 5 minute setting is twelve times the runs on the most expensive serverless multiplier Snowflake publishes for this feature. That pressure is real, and it pushes teams toward checking less often than the pipeline deserves. A flat monthly tier removes the tension entirely: the honest monitoring schedule and the cheap monitoring schedule become the same schedule.
One place where freshness, volume and schema sit together
Freshness alone answers whether something arrived, not whether the right amount arrived or whether the columns still mean what they meant last week. In practice the incidents that cost the most are combinations: the table loaded on time, at ten percent of normal volume, because an upstream filter changed. Watching the four pillars against one baseline, in one incident timeline, is what turns three separate green checks into one honest red one.
How it works
From connected to caught
Connect Snowflake with a read only role
Create a role with read access to the databases you want watched. Dataobservability reads INFORMATION_SCHEMA, table metadata and query history to build the table inventory and the freshness and volume picture, so table contents are not copied out of Snowflake. There is no agent to install, no warehouse to resize and no pipeline change. Enterprise Edition is not required, because the monitoring does not depend on data metric functions.
Let the baseline form before you touch a threshold
Give it a few days of history per table so the load pattern becomes visible, including the weekly and monthly shapes. Tuning thresholds before a baseline exists is how teams manufacture alert fatigue in week one and stop trusting the monitoring in week two. On day one the correct amount of configuration is close to none.
Write explicit rules only for the invariants statistics cannot know
A learned baseline will tell you that a table usually loads by 06:00 and usually gains around 40,000 rows. It cannot know that revenue must never be negative, that a customer id must be unique, or that a regulatory extract has to land before 09:00 Eastern regardless of what it usually does. Those are the rules worth writing by hand, and there are far fewer of them than a rules first approach implies.
Route by ownership, then let the noise level settle
Send the tables that page someone to PagerDuty and everything else to Slack. Assign owners per schema so the alert arrives with a name attached. Review the first two weeks of alerts and mute the patterns that were true but not actionable, which is the step most teams skip and then blame the tool for.
What Snowflake data metric functions actually cost, and why ROW_COUNT is the cheap one
Snowflake publishes the arithmetic, but it lives in the Service Consumption Table rather than in the data quality documentation, so most teams adopt data metric functions without ever seeing it. Here is the chain. Data Quality Monitoring is a Serverless Feature, and Serverless Features are billed at the rate of one Platform Credit per Compute-Hour, multiplied by the applicable feature multiplier. A Compute-Hour is defined as the computing resources comparable to running an XS Virtual Warehouse for one hour, calculated on a per second basis and rounded up to the nearest whole second. In Table 5, the Serverless Feature Table, Data Quality Monitoring carries a Snowflake-managed compute multiplier of 2 and a Cloud Services multiplier of 1, with no unit charges. Then comes the detail worth the whole page: footnote 12 states that the ROW_COUNT DMF uses a Snowflake-managed compute multiplier of 0.9. So the cheapest possible check, counting rows, is carved out at 0.9, and every other data metric function you would actually reach for, freshness, null counts, duplicates, schema change, and anything custom you write, bills at 2. Set that next to the neighboring rows in the same table. Serverless Tasks bill at 0.9. Serverless Alerts bill at 0.9. Serverless Tasks Flex bills at 0.5. Which means the identical SQL, scheduled as a serverless task instead of associated as a data metric function, carries roughly a fifth of the multiplier at the Flex rate and under half at the standard task rate. You lose the results view, the Snowsight data quality surface and the tidy association model, and you keep the logic and most of the credits. None of this makes the feature bad. It does mean that the sentence teams tell themselves, that native checks are free because they are already paying for Snowflake, is not accurate, and the gap widens with exactly the behavior that good monitoring requires.
The scheduling model, the six allowed intervals, and the detection latency they imply
DMF scheduling changed in a way that quietly matters. Historically an object had no default schedule, and a data metric function associated with a table simply would not run until somebody set DATA_METRIC_SCHEDULE. That failure mode was loud in a useful way: nothing ever fired, so somebody noticed. The parameter now defaults to 60 MINUTE, so an association made without thought evaluates hourly. The failure mode is now quieter and more expensive, because a check that runs hourly looks like monitoring while giving you an hour of blind spot on a table that loads every fifteen minutes. Three scheduling shapes are available. The first is an interval in minutes, and it is not free form: for data metric functions the documentation says to use one of the following values, 5, 15, 30, 60, 720, or 1440. That is the entire menu, so your detection latency is chosen from six options rather than tuned. The second is a cron expression with a time zone, written for example as USING CRON 0 6,12,18 * * * UTC. The third is TRIGGER_ON_CHANGES, which specifies that the DMF runs when a DML operation modifies the table, such as inserting a new row or deleting a row, and which carries a documented exclusion worth knowing before you rely on it: a DML event that involves reclustering does not count. There is also a lag on both ends of a change. It takes ten minutes for the schedule to become effective once the schedule is set, and ten minutes once the DMF is unset for the scheduling changes to take effect. Read the interval menu and the 2x multiplier together and the design pressure becomes obvious. Every step you take toward faster detection multiplies evaluations against the most expensive multiplier in the feature table, so the schedule stops being an engineering decision about the pipeline and becomes a budget negotiation.
What the FRESHNESS data metric function returns, and where the number stops being enough
FRESHNESS is a genuine primitive and it is worth understanding precisely, because the gap between it and a monitoring system is exactly the work you would otherwise be quoted for. Called directly it takes a query projecting a single timestamp column, of type DATE, TIMESTAMP_LTZ or TIMESTAMP_TZ, and returns a scalar NUMBER: the elapsed seconds since the table was last modified, or since the newest value in the column you nominated. Associated with an object it can take the column argument optionally for a table, and must take it for a view or an external table. Alongside it sits DATA_METRIC_SCHEDULED_TIME, which returns a TIMESTAMP_LTZ giving the time the DMF was scheduled to run, or the current timestamp when called manually, and which exists so you can write custom freshness metrics that compare the data against when the check was meant to run rather than when it happened to run. That is a clean, cheap, well documented measurement layer. What it is not is a decision. Nothing in the function knows that 5,400 seconds is fine for the marketing attribution table and a serious problem for the payments reconciliation table, because that judgment lives in your business and not in Snowflake metadata. So the moment you have the number you own the rest: a threshold per table, a way to hold thresholds under version control, a query that reads DATA_QUALITY_MONITORING_RESULTS on a schedule, deduplication so a table stale for nine hours generates one incident rather than nine, an owner per schema, and a path to whoever is carrying the pager. Every one of those is buildable. Together they are the product, and they are the reason a team that starts with FRESHNESS in March is frequently still maintaining a homegrown alerting layer in September.
The full system metric catalogue, and the shape of the gaps in it
Snowflake groups its system data metric functions into six categories in the SNOWFLAKE.CORE schema, and reading them as a set tells you what the feature was designed to do. Accuracy is by far the largest group and is where most of the rule checking lives: NULL_COUNT and NULL_PERCENT, BLANK_COUNT and BLANK_PERCENT, ZERO_COUNT and ZERO_PERCENT, NEGATIVE_COUNT and NEGATIVE_PERCENT, INVALID_JSON_COUNT and INVALID_JSON_PERCENT, INVALID_NUMERIC_TYPE_CAST_COUNT and its percentage twin, CASE_FORMAT_VIOLATION_COUNT, SPECIAL_CHARACTER_COUNT, UNTRIMMED_STRING_COUNT, FUTURE_TIMESTAMP_COUNT and the matching percentages. Uniqueness gives you DUPLICATE_COUNT, UNIQUE_COUNT and ACCEPTED_VALUES, which determines whether values in a column match a Boolean expression. Volume gives you ROW_COUNT. Freshness gives you FRESHNESS and DATA_METRIC_SCHEDULED_TIME. Schema gives you SCHEMA_CHANGE_COUNT, which detects column additions, deletions, renames and type modifications. Statistics gives you the descriptive set: AVG, MIN, MAX, MEDIAN, STDDEV, VARIANCE, the approximate quantiles at 25, 50 and 99, and the string length aggregates. That is a strong measurement catalogue by any standard, and if there is no system metric for what you need, you can define a custom DMF in SQL. The gaps are not in the metrics, they are in everything that turns a metric into an operational signal. There is no learned baseline, so every one of those numbers needs a threshold typed by a human who has to guess it. There is no distribution monitoring in the sense of noticing that a column that is normally 3 percent null became 19 percent null on Thursday, only a null percentage you compare against a constant you chose. There is no incident model, so nine consecutive hourly failures are nine rows rather than one open incident with an owner. That is the honest division of labour: Snowflake measures, and you build the judgment.
Why the last modification time is the most misleading freshness signal in a warehouse
The single most common homegrown freshness check in Snowflake is a query over INFORMATION_SCHEMA that reads LAST_ALTERED and compares it to the current timestamp. It costs nothing, it runs on any edition, and it is wrong in a specific direction that makes it dangerous: it fails green. LAST_ALTERED reflects modification of the table object, and a table object is modified by a great many operations that are not the arrival of the rows anyone is waiting for. A truncate and reload that truncated and then failed before the load moved the clock. A backfill of last quarter moved the clock. A column addition moved the clock. A merge that matched nothing and wrote nothing still ran. In each case the metadata says the table is fresh and the dashboard is stale, which is the worst available outcome because the monitoring is actively supplying false confidence. This is not unique to Snowflake. The equivalent trap on Delta tables is that OPTIMIZE and VACUUM write new table versions without writing data, so a raw commit time check reports fresh on a table that has received nothing for a day. The fix in both cases is the same in principle: derive freshness from the pattern of loads observed over time, not from a single timestamp asserted by the catalog, and compare what happened against what usually happens.
Getting the alert out of Snowflake, which is where most native setups stall
Detection without delivery is a report nobody reads. Snowflake supports notifications for data quality issues through a notification integration, and the setup is a sequence: create the integration, grant the necessary privileges, turn notifications on for the database, and name the integration that will send them. Once enabled at database level the default is broad, meaning data quality issues on any object in that database generate a notification, and you narrow it by setting DATA_QUALITY_NOTIFICATION to FALSE on individual associations. The constraint that stops teams is on the email path. Snowflake documentation is direct about it: you can send email notifications only to Snowflake users within the same account, and every address listed in ALLOWED_RECIPIENTS must be verified first. Read that against how an on call rotation actually works. The address you want to page is a PagerDuty inbound address, a shared alias, or a Slack channel email, and none of those are a verified Snowflake user in your account. Teams work around it, usually with a task that queries the results view and calls an external function or a webhook, and that workaround is a small distributed system with its own failure modes, its own secrets and its own on call implications. It is entirely reasonable engineering. It is also two to three weeks of work to reach the point where a stale table reliably reaches a human, which is where a monitoring product starts.
The edition gate, the association ceiling, and what is not covered at all
Data Quality Monitoring in Snowflake requires Enterprise Edition. If your account is on Standard, the system data metric functions are not a configuration change away, they are an upgrade conversation, and the cost of that upgrade dwarfs the cost of most monitoring tools. That single fact reorders the build versus buy math for a large number of teams before any feature comparison starts. Trial accounts do not support the feature either, so you cannot evaluate it before you commit to the edition that carries it. For accounts that are on Enterprise, the documented ceiling is 50,000 total associations of DMFs on objects per account, where each assignment of a function to a table or view counts as one. That is a large number and few teams will approach it, but it is worth knowing that the unit of accounting is the association rather than the table, so five checks across ten thousand tables is a different arithmetic than one. Coverage has real edges too. Data metric functions cannot be applied to hybrid tables or to stream objects, and you cannot grant privileges on a DMF to a share or set a DMF on a shared table or view, which matters if a meaningful part of your critical data arrives through Snowflake data sharing. Standard tables, views, external tables, event tables, dynamic tables, materialized views and Apache Iceberg tables are supported. The point of listing this is not that Snowflake is deficient. It is that a coverage map with holes in it is not a coverage map you can hand to an auditor or to a new engineer, and reconstructing which objects are actually watched is the kind of question a monitoring layer should answer in a screen rather than in a spreadsheet.
What a Snowflake data quality incident looks like when the monitoring is doing its job
Take the case that costs the most: the daily orders table loads on time at 04:00, and at 09:00 the revenue dashboard is visibly wrong. A FRESHNESS check would have reported green all morning, because the load happened. Volume caught it: the table gained 3,100 rows against a weekday baseline near 41,000, which is a change most fixed thresholds would ignore because it is not zero. Schema explains it: an upstream system started sending a new value in a status column, and a filter in the staging model dropped everything that did not match the known set. Lineage closes it: the same staging model feeds four dashboards and one reverse ETL sync to the CRM, so the blast radius is known before anyone asks. That sequence is why the pillars belong on one baseline and in one incident rather than in four scheduled evaluations. The freshness check is the cheapest of the four to build and the least likely on its own to catch the incident that actually damages trust. Monitoring the load pattern, the volume, the schema and the distribution of the columns that matter, against what each table normally does, is the difference between finding out at 04:15 from an alert and finding out at 09:00 from the head of sales.
Questions buyers ask
Snowflake data metric functions FAQ
How much do Snowflake data metric functions cost?
They bill as the Data Quality Monitoring serverless feature: one Platform Credit per Compute-Hour multiplied by a feature multiplier of 2, plus cloud services at 1. ROW_COUNT is the documented exception at 0.9. A Compute-Hour is the equivalent of an XS warehouse for an hour, measured per second and rounded up.
Why does ROW_COUNT cost less than other data metric functions?
Because Snowflake carves it out explicitly. Footnote 12 of the Serverless Feature Table states that the ROW_COUNT DMF uses a Snowflake-managed compute multiplier of 0.9, against 2 for the rest of Data Quality Monitoring. The practical effect is that the cheapest volume check is priced below the freshness, null and schema checks most teams actually want.
How often can a Snowflake data metric function run?
From every 5 minutes to once a day, chosen from a fixed menu. For the minutes form the documentation says to use one of the following values: 5, 15, 30, 60, 720, or 1440. You can also use a cron expression with a time zone, or TRIGGER_ON_CHANGES to evaluate on DML. Schedule changes take ten minutes to become effective.
What is the default schedule for a Snowflake data metric function?
One hour. The DATA_METRIC_SCHEDULE parameter defaults to 60 MINUTE, so a data metric function associated with an object begins evaluating hourly without any further configuration. On a table that loads every fifteen minutes that default is three quarters of an hour of blind spot, and it is easy to inherit without ever making the decision.
Can I create a custom data metric function in Snowflake?
Yes. Snowflake documentation states that if there is not a system DMF for the metric you want to monitor, you can define a custom DMF in SQL. It bills under the same Data Quality Monitoring feature at the 2 multiplier, and you take on the SQL, the tests for that SQL, and keeping it under version control as the schema underneath it changes.
Do Snowflake data metric functions require Enterprise Edition?
Yes. Data Quality Monitoring, including every system data metric function, requires Enterprise Edition, and trial accounts do not support the feature. Accounts on Standard cannot enable it with a configuration change. For teams weighing native checks against a monitoring tool, the edition upgrade is frequently the larger line item and is worth pricing before the feature comparison begins.
How many data metric functions can I attach in one Snowflake account?
The documented ceiling is 50,000 total associations of data metric functions on objects per account, where each assignment of a function to a table or a view counts as one association. Note the unit: five checks across ten thousand tables consumes the same budget as one check across fifty thousand. In practice teams hit the limit of who will maintain the associations long before they hit 50,000.
Which Snowflake objects cannot be monitored with data metric functions?
Data metric functions cannot be applied to hybrid tables or to stream objects, and you cannot set a data metric function on a shared table or view or grant privileges on one to a share. Standard tables, views, external tables, event tables, dynamic tables, materialized views and Iceberg tables are supported. If critical data reaches you through Snowflake data sharing, map that gap first.
Can Snowflake send a data quality alert to Slack or PagerDuty?
Not directly on the email path. Snowflake sends data quality notifications through a notification integration, and the documentation is explicit that email notifications can go only to Snowflake users within the same account, with every address in ALLOWED_RECIPIENTS verified first. Reaching a PagerDuty inbound address or a shared on call alias means building a task that reads the results view and calls a webhook.
Why does my Snowflake table look fresh when the data is stale?
Because the signal you are reading is a modification timestamp, not a load. LAST_ALTERED and a raw last modified time move on any operation that touches the table, including a failed truncate and reload, a backfill, a column addition, or a merge that matched no rows. Each of those reports fresh while no new data arrived. Deriving freshness from the observed load pattern closes that gap.
What does Dataobservability cost for a Snowflake account?
Plans start at 99 dollars a month for Starter, 299 for Team and 799 for Scale, with a 14 day trial and no card required. Pricing is published rather than quoted, and it does not meter per monitor or per monitored table, so widening coverage across more Snowflake schemas does not increase the bill. Snowflake, BigQuery, Databricks and Redshift are included at every tier.
More of the platform
Catch broken data before your stakeholders do
Connect your warehouse and get snowflake data metric functions live from one read-only connection. Transparent pricing, no credit card.