Skip to main content
Monitors as code lets you define Sidecar monitors next to the dbt models they protect. The definitions live in your repository, go through your normal pull request review, and Sidecar creates and updates the monitors from them. Once synced, they look and behave like any other monitor. You can define monitors in two places, and mix both in one project:
  • In a model’s YAML, under config.meta.sidecar. The definition ships with the model and reaches Sidecar through your production dbt run.
  • In one file per repository, sidecar/monitors.yml. Sidecar reads it from your Git provider’s default branch on each sync, so merged changes are picked up without a dbt run.

Before you start

  • Connect dbt Cloud or dbt Core. Sidecar reads monitor definitions from the dbt models it has already catalogued.
  • Connect the warehouse your models build into, for example Snowflake or BigQuery. Volume and freshness monitors bind to the warehouse table behind each model.
  • To use the repository file, connect GitHub or GitLab so Sidecar can read sidecar/monitors.yml.

Define monitors in a model’s YAML

Add a sidecar block under the model’s config.meta. The keys under monitors are the monitors’ identities, so pick stable names.
models/marts/fct_orders.yml
Write the block under config.meta, not top-level meta. dbt carries it into the manifest and the Discovery API, which is where Sidecar reads it.

Define monitors in a repository file

Create sidecar/monitors.yml at the root of the dbt repository. Each entry names a model and uses the same monitor schema as the model YAML.
sidecar/monitors.yml
Use name when the model name is unique in your project, or unique_id to be explicit. Defaults apply in this order: file defaults, then entry defaults, then the monitor’s own fields.
A monitor is identified by its model and key. Moving a definition between the model YAML and the repository file keeps the monitor and its run history. Defining the same key for the same model in both places is a conflict, and both definitions are blocked until you remove one.

Monitor reference

Common fields

Custom

Reference tables with [[ this ]] for the current model or [[ ref('model_name') ]] for another model. Sidecar resolves each to the fully qualified warehouse table. Jinja {{ ref() }} is not supported inside monitor SQL.

Volume

Volume monitors bind to the warehouse table behind the model. The model must be materialized as a table.

Freshness

Schedules

Notification destinations

Sync your monitors

1

Merge your definitions

Open a pull request with the YAML changes and merge it. For model YAML, run your production dbt job afterward so the new metadata reaches Sidecar.
2

Click Sync from dbt

In Sidecar, open Observability → Monitors and click Sync from dbt. The button is also on Observability → Asset monitors.
3

Complete the one-time setup

The first time, a dialog asks for your dbt environment, the warehouse to run custom SQL on, and whether to read sidecar/monitors.yml. Confirm, and the first sync runs immediately.
4

Review the result

A toast summarizes what changed, for example “Synced from dbt: 3 created, 1 unchanged”. If any definition could not be applied, a panel lists it with the reason.
After setup, Sidecar syncs automatically whenever it refreshes your dbt catalog. Use the button when you want a change applied right away.
Repository file changes are picked up by the next sync after they are merged. Model YAML changes need a production dbt run first, then Sidecar’s next catalog refresh.

How changes flow

If a monitor already exists on a table from the UI when you add a volume or freshness definition for the same table, the sync pauses on it and offers Adopt. Adopting hands the existing monitor and its history over to the code definition.

Let your coding agent write them

If you use Claude Code, Cursor, or Codex in your dbt repository, install the agent skill for monitors as code. It teaches the agent the schema and the rules on this page so it produces valid definitions.

Troubleshooting

The panel shows an error code and message for each blocked definition. Common codes: table_not_found when the model has no warehouse table in the catalog, asset_not_eligible when the model is a view, unsupported_freshness_mode for last_updated on Redshift, warehouse_mismatch when custom SQL references tables outside the warehouse chosen at setup, and duplicate_key when the same key is defined in both the model YAML and the repository file. Other definitions still apply.
Sidecar reads model YAML from your production dbt run. Run the production job, wait for Sidecar’s catalog refresh, then sync again. Make sure the block is under config.meta.sidecar.
A skipped sync means Sidecar could not get a complete picture and changed nothing. The toast names the reason, for example file_unreadable when sidecar/monitors.yml is missing on the branch. If you removed the file on purpose, use Stop reading sidecar/monitors.yml in the panel.
When Sidecar cannot read a model’s block or the repository file, it keeps the monitors that came from that source rather than guessing. Fix the YAML and sync again.