Skip to content

SQLMesh Plans

Quick Summary

A SQLMesh plan compares your current model definitions against the state database to detect what has changed. dagctl wraps this process in a structured workflow: create, review, approve, and execute. Plans are required before modified models will run with updated logic.

What Is a SQLMesh Plan

When you change a model - its SQL, grain, partitioning, or cron schedule - SQLMesh needs to know what intervals require reprocessing. A plan runs sqlmesh plan to detect those changes, determines which historical intervals need backfilling, and produces an explicit change summary before anything executes.

dagctl surfaces this workflow in the web UI with an approval gate. No changes apply to your warehouse until a plan is approved and executed.

Plan Workflow

1. Create

A user triggers a plan from the web UI on the project's Plans tab. dagctl creates a Kubernetes Job that runs:

sqlmesh plan --explain <environment>

The --explain flag produces the change summary without applying anything. The pod runs against the same state database your production jobs use.

2. Review

The Job Watcher monitors the pod output. When the job completes, it parses the model change summary and backfill scope, then surfaces the diff in the web UI. You can see:

  • Which models changed and how
  • Which historical intervals will be backfilled
  • The full sqlmesh plan output for debugging

3. Approve

A plan stays in pending status until it is approved. Approving requires the approve_plan permission, which the Owner, Admin, and Developer roles hold — see Organizations for the role matrix.

Automated approval

If a project has automated remediation with auto-merge enabled, a plan created by that workflow may be approved and executed automatically, recorded under a system actor rather than a user. This is off by default and must be enabled per project.

Warning

Approving a plan authorizes execution of the backfill scope shown at review time. If your repository has changed since the plan was created, the backfill may no longer reflect the current model state. Re-create the plan if significant time has passed or additional commits have merged.

4. Execute

After approval, dagctl creates a Kubernetes Job that runs:

sqlmesh plan --auto-apply <environment>

This applies the plan and kicks off backfill execution for any affected intervals. The execution pod uses the same credentials and state connection as your scheduled jobs.

5. Complete

The Job Watcher reports the final status back to the web UI. Backfill progress is visible in the plan detail view. Once complete, your next scheduled sqlmesh run job will process intervals using the updated model logic.

Model Change Types

Change Type Description
Added A new model that did not exist in the prior state
Removed A model that existed in prior state but is no longer defined
Directly Modified The model's SQL or configuration was changed directly
Indirectly Modified An upstream dependency was modified, causing this model to be re-evaluated
Breaking Change A change that alters the model's grain, partitioning, or output schema

SQLMesh classifies directly and indirectly modified models differently because they have different backfill implications. An indirect change only requires reprocessing if the upstream change was breaking.

Backfills

When models are modified, SQLMesh calculates which historical intervals need reprocessing based on the change type and the model's cron schedule. The plan shows the full backfill scope before execution begins.

Backfill scope is bounded by:

  • The model's start date - No data before this date is reprocessed
  • The change type - Non-breaking changes may not require a backfill
  • The environment's interval history - Only intervals previously completed are considered for reprocessing

Large backfills run as part of plan execution and can take significant time. Monitor progress in the plan detail view. If a backfill is interrupted, re-running the plan will resume from where it stopped.

Warning

Breaking changes on high-volume models can generate large backfills. Review the backfill scope carefully before approving. If the scope is larger than expected, check whether the change was classified correctly by SQLMesh - a FULL backfill on a model with years of history will be expensive.

Environments

Environment Use Case
prod Live production data
dev Local and team development
preview Pre-production review before promoting to prod

Every plan requires approval before it executes, regardless of environment. Who can approve is controlled by role permissions at the organization level, not per environment.

Separately, environment protection restricts which users can connect to a given environment from the dagctl CLI during local development. Protection records are organization-scoped and configured under Settings → Secrets → Protection. See Environment Protection.

Preview environments are useful for validating model changes against a copy of production data before running a plan against prod.

Next Steps