Asset-level data quality

How many of your tables passed, which data quality dimension fails and which tables failed, for the whole account or a domain, data product, asset tag or warehouse.

ℹ️

Private preview

Composable dashboards and the metrics API are in private preview: available to invited accounts, and features may change. See Integration and feature lifecycles for what this means, and reach out to your account representative to request access.

Overview

Data quality measured per table rather than per monitor: the share of tables with a result this week that had no data quality alert. Use it to see whether a group of tables can be trusted, which data quality dimension fails and which tables to fix first.

For: data team leads, data product owners. Metrics: Data quality.

Asset-level data quality dashboard, rendered from this example

An example built from the prompt below, with sample names and values.

Prompt

Copy one of these prompts into an AI tool connected to the Monte Carlo MCP server. With the dashboard skills from the Monte Carlo agent toolkit installed (in coding agents such as Claude Code, Cursor, Codex and GitHub Copilot), your agent reads this page, builds the layout and runs the queries below; without them, it works from the metrics alone.

Build a data quality dashboard for the tables behind my domains this week, by data quality dimension, with the tables that had the most alerts.

By data product:

Build a data quality dashboard for the tables behind my data products this week, by data quality dimension, with the tables that had the most alerts.

What it covers

  • An overall data quality score: the share of your tables with a result this week that had no data quality alert.
  • A score for each data quality dimension (Accuracy, Completeness, Timeliness and so on), worst first.
  • The domains or data products with the lowest score, and the monitors that alerted.
  • Which tables are failing, on which data quality dimensions, and how many alerts they had.
  • This score counts tables, not monitors, so it differs from the Data quality dashboard in Monte Carlo.

Filters and groupings

  • By domain, data product or asset tag, with their domain_, data_product_ and asset_tag_ health metrics, or by warehouse.
  • Broken down by data quality dimension, monitor type or monitor priority.
  • Windows: the last 1, 7, 30 or 90 days up to the last data refresh. Health keeps no history, so there is no date range or trend.
  • Data quality dimensions inside one domain, data product or asset tag take two steps: list its tables, then filter on them.

How it's built

The layout, queries and definitions your agent follows; use them to check its numbers or to build the dashboard by hand. The queries below are for domains; data products and asset tags use the data_product_ and asset_tag_ metrics the same way.

Layout

  1. Filter: the domain or data product, all tables by default.
  2. The answer: asset health, with "N of M tables passing". Health keeps no history yet, so there is no trend.
  3. By data quality dimension: each dimension with its health and "x of y tables", worst first; "Not classified" last. With a domain or data product selected, the dimensions count its tables only (two steps, see the queries).
  4. Worst domains or data products: the 10 with the lowest health, and how many more; the ones with no result last, marked "no result".
  5. Monitors that alerted: each monitor with an alert in the window, with its type, data quality dimension, last run and the number of tables it alerted on, most tables first.
  6. Tables: one row per table with a result, failing first, then by alerts: the table, its status (passing or failing), the data quality dimensions that failed and its alerts in the last 7 days.

Queries

BlockWindow
Filter, the answer, by data quality dimension, worst domains, tableslast 7 days up to the last data refresh
Alerts per tablelast 7 days

Filter and worst domains: domains, worst first

Request (JSON)
{
  "metrics": ["domain_asset_health_score_7d"],
  "group_by": ["domain", "domain__domain_name"],
  "order_by": [{"field": "domain_asset_health_score_7d"}]
}

Domains with no table with a result get no row: take every domain from this query (data products: data_product_count, without deleted ones) and mark the missing ones "no result".

  • Metrics: domain_count
  • Grouped by: domain, domain__domain_name
Request (JSON)
{
  "metrics": ["domain_count"],
  "group_by": ["domain", "domain__domain_name"]
}

The answer, all tables. Passing tables are the ones with a result minus the failing ones.

Health:

Request (JSON)
{"metrics": ["asset_health_score_7d"]}

Tables with a result:

Request (JSON)
{
  "metrics": ["population_assets"],
  "filters": [
    {
      "field": "asset__is_asset_with_result_7d",
      "op": "in",
      "values": [true]
    }
  ]
}

Failing tables:

Request (JSON)
{
  "metrics": ["population_assets"],
  "filters": [
    {
      "field": "asset__is_asset_alerting_7d",
      "op": "in",
      "values": [true]
    }
  ]
}

The answer, one domain: the same metrics with the domain_ prefix (domain_asset_health_score_7d, domain_population_assets with the same two filters), filtered on its name.

Request (JSON)
{
  "metrics": ["domain_asset_health_score_7d"],
  "filters": [
    {
      "field": "domain__domain_name",
      "op": "in",
      "values": ["<selected domain>"]
    }
  ]
}

By data quality dimension: health and tables with a result. Monitors without a data quality dimension come back with it empty: show them as "Not classified".

Request (JSON)
{
  "metrics": [
    "monitor_asset_health_score_7d",
    "monitor_assets"
  ],
  "group_by": ["monitor__monitor_data_quality_dimension"],
  "filters": [
    {
      "field": "monitor_asset_quality__is_monitor_asset_with_result_7d",
      "op": "in",
      "values": [true]
    }
  ]
}

For one domain or data product, take its tables first and add a filter on them, as Combining groupings on the Dimensions page says. The same filter applies to the two queries below.

  • Metrics: domain_population_assets
  • Grouped by: asset__asset_mcon
  • Filter: domain__domain_name is the selected domain
  • At most 10,000 rows
Request (JSON)
{
  "metrics": ["domain_population_assets"],
  "group_by": ["asset__asset_mcon"],
  "filters": [
    {
      "field": "domain__domain_name",
      "op": "in",
      "values": ["<selected domain>"]
    }
  ],
  "limit": 10000
}

Then: Filter: asset__asset_mcon is one of those tables.

By data quality dimension: tables failing

  • Metrics: monitor_assets
  • Grouped by: monitor__monitor_data_quality_dimension
  • Filter: monitor_asset_quality__is_monitor_asset_alerting_7d is true
Request (JSON)
{
  "metrics": ["monitor_assets"],
  "group_by": ["monitor__monitor_data_quality_dimension"],
  "filters": [
    {
      "field": "monitor_asset_quality__is_monitor_asset_alerting_7d",
      "op": "in",
      "values": [true]
    }
  ]
}

Monitors that alerted

  • Metrics: monitor_assets
  • Grouped by: monitor, monitor__monitor_name, monitor__monitor_type, monitor__monitor_data_quality_dimension, monitor__monitor_last_run_at
  • Filter: monitor_asset_quality__is_monitor_asset_alerting_7d is true
  • Sorted by: monitor_assets, highest first
Request (JSON)
{
  "metrics": ["monitor_assets"],
  "group_by": [
    "monitor",
    "monitor__monitor_name",
    "monitor__monitor_type",
    "monitor__monitor_data_quality_dimension",
    "monitor__monitor_last_run_at"
  ],
  "filters": [
    {
      "field": "monitor_asset_quality__is_monitor_asset_alerting_7d",
      "op": "in",
      "values": [true]
    }
  ],
  "order_by": [
    {"field": "monitor_assets", "descending": true}
  ]
}

With a member selected, filter on its tables as above.

Tables: status. A table is failing when it had a data quality alert in the window. For one domain, ask domain_population_assets with the same filter.

  • Metrics: population_assets
  • Grouped by: asset, asset__asset_full_table_id, warehouse__warehouse_name, asset__is_asset_alerting_7d
  • Filter: asset__asset_category is table; asset__is_asset_with_result_7d is true
  • At most 10,000 rows
Request (JSON)
{
  "metrics": ["population_assets"],
  "group_by": [
    "asset",
    "asset__asset_full_table_id",
    "warehouse__warehouse_name",
    "asset__is_asset_alerting_7d"
  ],
  "filters": [
    {
      "field": "asset__asset_category",
      "op": "in",
      "values": ["table"]
    },
    {
      "field": "asset__is_asset_with_result_7d",
      "op": "in",
      "values": [true]
    }
  ],
  "limit": 10000
}

A table's full name can be in several warehouses, each a table of its own: keep one row per asset, never merge rows by name, and show its warehouse next to a name that repeats.

Tables: failing data quality dimensions

  • Metrics: monitor_assets
  • Grouped by: asset, monitor__monitor_data_quality_dimension
  • Filter: asset__asset_category is table; monitor_asset_quality__is_monitor_asset_alerting_7d is true
  • At most 10,000 rows
Request (JSON)
{
  "metrics": ["monitor_assets"],
  "group_by": [
    "asset",
    "monitor__monitor_data_quality_dimension"
  ],
  "filters": [
    {
      "field": "asset__asset_category",
      "op": "in",
      "values": ["table"]
    },
    {
      "field": "monitor_asset_quality__is_monitor_asset_alerting_7d",
      "op": "in",
      "values": [true]
    }
  ],
  "limit": 10000
}

Tables: alerts in the last 7 days

  • Metrics: asset_incident_count
  • Grouped by: asset
  • Filter: metric_time__day on or after 7 days ago; asset__asset_category is table; incident__incident_type is not one of "etl_errors", "dbt_errors"
  • Sorted by: asset_incident_count, highest first
  • At most 10,000 rows
Request (JSON)
{
  "metrics": ["asset_incident_count"],
  "group_by": ["asset"],
  "filters": [
    {
      "field": "metric_time__day",
      "op": "gte",
      "values": ["<7 days ago>"]
    },
    {
      "field": "asset__asset_category",
      "op": "in",
      "values": ["table"]
    },
    {
      "field": "incident__incident_type",
      "op": "not_in",
      "values": ["etl_errors", "dbt_errors"]
    }
  ],
  "order_by": [
    {"field": "asset_incident_count", "descending": true}
  ],
  "limit": 10000
}

Join the three table queries on asset. For one member, keep the failing data quality dimensions and alerts of its tables only.

Definitions

  • Asset health counts tables; the product's Data quality score scores Table Monitors per table and other monitors per monitor, from their latest results; the Data quality metrics page says how, and how to show a trend.
  • An alert counts against every table it concerns, once per table, and once per domain or data product of those tables.
  • Data products count the tables a user added plus the tables upstream of them in lineage. Domains here are table membership (domain__domain_name).
  • Not classified: monitors without a data quality dimension are often most of them; then most failing tables list only "Not classified". Say so under By data quality dimension, with what it means: the data quality dimension is set on each monitor, and these monitors have none.
  • Job failures (Airflow, dbt, Databricks, Data Factory) are not data quality alerts: they do not make a table fail, and the alerts per table leave them out.
  • Two windows: status counts the last 7 days up to the last data refresh, alerts whole days from 7 days ago, so a passing table can show an alert from just before its window.

Did this page help you?