Upgrading from dbt v1 to dbt v2: A Practical Guide for Snowflake Teams
Quick answer: dbt v2, the Rust engine previously called Fusion, was released on 14 September 2026 and announced as generally available at dbt Summit, Snowflake included. pip install dbt now installs it, and dbt v1 is still supported. To upgrade, clear every deprecation on dbt 1.12 with dbt-autofix, check packages and move one project at a time, since v1 can read the manifest v2 writes. On Snowflake, move key pair authentication to PKCS#8 first, and replace the dbt Snowflake Native App now, because it is due to be removed in November 2026.
Last updated: October 2026
dbt v2 is the engine dbt Labs spent about 18 months building under the name Fusion, a single Rust binary that parses the SQL in your models and doesn't need Python. Since September 2026 it has been called dbt, and pip install dbt now installs it, so even a team that isn't ready to move needs a plan.
v2 is also stricter. A config typo that v1 ignored without a warning is a parse error in v2, and a call to a macro that doesn't exist fails at parse time. Much of what fails during an upgrade comes from old mistakes and deprecated patterns that v1 accepted.
What dbt v2 is, and what happens to dbt v1
| Name now | What it is | Licence |
|---|---|---|
dbt v2 (the dbt package) | The Rust engine with SQL comprehension, static analysis, the language server, dbt lint and the VS Code extension | Proprietary to dbt Labs, free to use |
dbt OSS (dbt-oss) | The same Rust runtime without SQL comprehension, static analysis, LSP features or dbt lint | Apache 2.0 |
| dbt v1 | dbt Core 1.x, the Python engine | Apache 2.0 |
dbt Labs recommends the full dbt distribution for almost everyone, and dbt OSS only where a licence policy requires Apache 2.0 or a team builds its own tooling on the runtime. The two can't share a Python environment.
You don't have to move yet. dbt Labs says v1 remains fully supported, although new capabilities will increasingly arrive in v2 only. dbt 1.12 has active support until 15 July 2027. dbt 1.11 leaves critical support on 18 December 2026, 1.8 to 1.10 are already deprecated, and dbt Labs will remove 1.3 to 1.7 from the dbt platform on 31 January 2027, so teams on those need 1.12 soon either way.
We also recommend pinning exact versions in CI and logging dbt --version in every job, so a new release can't change the engine unnoticed. On 24 October 2026, pip resolved dbt-core to 1.12.6 and dbt-snowflake to 1.12.4 from PyPI, both dbt v1, although a dbt Labs post of 16 September 2026 says both install v2 components. The v2 release history marks v2.0.7 as known bad, and on 24 October 2026 the recommended latest channel was at v2.0.9, released on 19 October 2026.
# dbt v1: pin the engine and the adapter. python -m pip install "dbt-core==1.12.6" "dbt-snowflake==1.12.4" dbt --version # dbt v2 from the standalone installer: pin a version not flagged known bad. dbt system update --version 2.0.9 dbt --version
Before you touch v2, get v1 clean
dbt Labs advises moving to dbt 1.12 first. Its requirements for v2 are a supported adapter and authentication method, Semantic Layer configurations on the latest YAML spec, and a project that runs on the latest v1 with no deprecation warnings or errors, old or new.
# On dbt v1, list every occurrence of each deprecation, # including those found only during a full parse. dbt parse --no-partial-parse --show-all-deprecations # On dbt 1.12 or later 1.x, parse with the Rust parser # without changing anything else. dbt parse --use-v2-parser
The most common deprecations are these.
- Custom keys under
configor at the top level of a YAML file move underconfig.meta. - Generic test arguments nest under a new
argumentsproperty, and properties such asmeta,tagsanddocsmove underconfig. - Hierarchical configs in
dbt_project.ymlneed the+prefix, andsource-paths,data-paths,log-pathandtarget-pathare fully deprecated in v2. - The
--modelsand-mflags raise an error in v2. Use--selector-sin job definitions as well as scripts. - Behaviour flags that v2 removes, such as
require_explicit_package_overrides_for_builtin_materializations, are always on in v2. Delete anyflags:overrides that opt out of them, and fix what that exposes while you are still on v1.
On the dbt platform, each project needs at least one job, every job must have run in the last seven days, and all jobs must succeed for the checks to work, so fix or delete failing and unused jobs first. The upgrade tools also need the v1 Latest track, a developer licence, the right permissions and an admin who has ticked Enable dbt v2 readiness & upgrade features. Enterprise accounts can limit the upgrade to the v2 Migration Admin permission set. If v2 Stable doesn't appear, ask your account team.
Let dbt-autofix do the mechanical work
dbt-autofix, dbt Labs' clean-up tool, moves properties under config and custom keys under meta, removes duplicate YAML keys, nests test arguments, converts old static_analysis values and adds + prefixes to built-in configs (custom configs still need them by hand). It also deletes target-path and log-path, so if CI reads manifest.json from a custom path, pass that path with --target-path in the dbt commands that write it before you apply the fixes. Behaviour-changing fixes, such as renaming resources (and their .sql files) with spaces, run only on request.
# Install, then preview first. Commit your work so the diff is easy to review. pip install dbt-autofix dbt-autofix deprecations --dry-run dbt-autofix deprecations # Behaviour-changing fixes are opt-in. dbt-autofix deprecations --behavior-change # Check and upgrade package versions, then reinstall them. dbt-autofix packages dbt deps
dbt-autofix jobs rewrites -m and --model to -s and --select in platform job steps, given an Admin API token with read and write access to jobs. The Studio IDE upgrade flow applies the same fixes. We recommend reviewing every key moved under meta, because a misspelled official config looks like a custom key, and under meta it has no effect and v2 no longer reports it.
Packages need their own check. dbt Labs lists dbt_utils, audit_helper, dbt_external_tables and dbt_project_evaluator as compatible; for others, look for the hub's v2-compatible badge or a require-dbt-version range that includes 2.0.0, and test them. Fivetran's source and transformation packages have merged, so fivetran/github_source becomes fivetran/github with its transformation models deactivated, as dbt's upgrade guide says; otherwise the combined package also builds its transformation models in Snowflake. An incompatible package can be reported to its maintainer, fixed or removed for now.
What v2 rejects that v1 accepted
These are the behaviour changes most likely to surface in a mature project.
| Area | dbt v1 | dbt v2 |
|---|---|---|
| Misspelled configs and unknown YAML keys | Silently ignored | Parse-time error |
| Calls to macros, tests or variables that don't exist | Passed parse, failed at compile | Fail at dbt parse |
| Standalone YAML anchors | Allowed at the top level | Must sit under a top-level anchors: key |
Custom keys read with config.get() | Worked when the key sat directly under config | Must move under meta, where config.get() returns the default with a warning on both engines; use config.meta_get() |
Unit tests in dbt build | Ran in lineage order | All run first, then the rest of the DAG |
threads on Snowflake | A fixed setting | A maximum; v2 manages parallelism itself |
| A model that fails to compile | Stopped compilation | Skips only its downstream nodes |
Legacy include and exclude keys, and many v1 event names, in warn_error_options | Enforced (include and exclude with a deprecation warning) | Ignored, with only a deprecation or startup warning |
We recommend checking the last row closely, because v2 only warns about it and every run still passes, so a CI gate that promoted warnings to errors on v1 can stop enforcing anything. Rewrite these settings with error and warn keys and v2 event names, and list the categories to enforce instead of error: all, because baseline static analysis emits warnings too. A numeric warning code stops dbt at startup. From dbt 1.12, v1 ignores v2-only event names, so the new settings can be written on v1 and shared by both engines.
dbt Labs says v2 supports nearly all of v1 and lists the gaps that may block a full move: materialisation features or configs not yet fully supported, tooling that depends on v1's exact log output, model-level notifications and SQLFluff. Platform runs on v2 have used dbt lint since July 2026, with results that can differ, while locally SQLFluff works with a standalone v1 templater. We recommend testing log parsers and alerting tools against a v2 run.
Snowflake specifics
- Key pair keys. v2 needs keys in PKCS#8 format, and dbt recommends AES-256 encryption. 3DES-encrypted, headerless and PKCS#1 keys aren't supported. We recommend converting affected keys before the upgrade, which keeps the same key pair, so nothing changes on the Snowflake user.
- Passwords on the dbt platform. New Snowflake credentials can't use a password. Key pair is the default, and existing password credentials need MFA and can't be edited until moved to key pair or OAuth.
- Drivers. v2 downloads ADBC drivers from dbt Labs' CDN on first run and caches them. If a firewall blocks that, ask dbt Labs for a supported offline option. As noted above,
pip install dbt-snowflakeinstalled v1 on 24 October 2026 (1.12.4 requires dbt-core below 2.0), not the v2 driver. - Static analysis gaps. dbt lists types and functions v2 can't yet analyse, such as
ARRAY,GEOGRAPHYandST_POINTFROMGEOHASH. In baseline mode these gaps only produce warnings. dbt advisesstatic_analysis: offonly where v2 can't parse valid Snowflake SQL, and off applies to every downstream model too, so we recommend using it on as few models as possible, as late in the DAG as you can. - Python models are supported on Snowflake in v2, materialised as
tableorincrementalonly. - Older adapters. Snowflake has announced larger default string and binary sizes (BCR-2118), 128 MB and 64 MB in place of 16 MB and 8 MB. dbt's docs gave September 2026, but on 24 October 2026 Snowflake listed the change as postponed, with no new date. When it arrives,
dbt-snowflakebelow 1.10.6 can fail incremental models with collated string columns andon_schema_change='sync_all_columns'. The fix is in 1.10.6, every platform release track and dbt v2.0.0.
# Keeps the same key pair. Prompts for the new passphrase, and for the old one if the key is encrypted. openssl pkcs8 -topk8 -v2 aes-256-cbc -inform PEM -in rsa_key_old.p8 -out rsa_key.p8
openssl genrsa 2048 | openssl pkcs8 -topk8 -v2 aes-256-cbc -inform PEM -out rsa_key.p8
That command creates a new private key. A Snowflake user can hold two public keys, so register the new one, update every profile, secret and job, and only then remove the old key.
# Extract the public key from the new private key. openssl rsa -in rsa_key.p8 -pubout -out rsa_key.pub -- In Snowflake, RSA_PUBLIC_KEY_FP and RSA_PUBLIC_KEY_2_FP show which slot is in use. DESC USER dbt_user; -- Add the key body to whichever slot is empty (this example assumes RSA_PUBLIC_KEY_2). ALTER USER dbt_user SET RSA_PUBLIC_KEY_2 = 'MIIBIjANBgkqh...'; -- Once every profile and job uses the new key, unset the other slot. ALTER USER dbt_user UNSET RSA_PUBLIC_KEY;
dbt ls -s config.materialized:incremental,config.on_schema_change:sync_all_columns --resource-type model
Snowflake's bundle 2026_07 also tightened GRANT OWNERSHIP on views and other owner-executed objects, which now needs the target role active in the session or account-level MANAGE GRANTS. Test any dbt hook or deployment step that transfers ownership in the same upgrade run. Our notes on Snowflake bundle 2026_07 explain the fix.
dbt Projects on Snowflake, and the end of the Native App
As of 24 October 2026, dbt Projects on Snowflake lists dbt 2.0.0 as an active version, next to dbt Core 1.9 to 1.12 and three 2.0.0-preview builds. Versions can be pinned per project, per run or as an account default, and a new default doesn't affect existing project objects, so projects can move one at a time. We recommend moving any project pinned to a preview build to 2.0.0 and running the comparison checks below.
Snowflake tracks support separately from dbt Labs. A version that dbt Labs no longer supports stays usable until Snowflake decommissions it, after which projects pinned to it fail until you update them. Our article on dbt Projects on Snowflake and column lineage covers version pinning in more detail.
SELECT SYSTEM$SUPPORTED_DBT_VERSIONS(); -- Try one run on dbt v2 without changing the project object. EXECUTE DBT PROJECT my_db.my_schema.my_dbt_project ARGS = 'build --target dev' DBT_VERSION = '2.0.0'; -- Pin the project once the comparison checks pass. ALTER DBT PROJECT my_db.my_schema.my_dbt_project SET DBT_VERSION = '2.0.0';
On 20 October 2026 Snowflake added a dbt State integration here. It needs a dbt platform account, a service token in a GENERIC_STRING secret and an external access integration for dbt Labs' hosts. dbt Labs runs and bills it under your own agreement, outside Snowflake's SLA, and runs still use Snowflake compute. If State can't authenticate, dbt v1 logs a warning and continues, but dbt v2 fails the run.
The dbt Snowflake Native App went into maintenance mode in July 2026 and will be removed in November 2026, on a day dbt Labs hasn't given. dbt Labs points users to the dbt Semantic Layer, which works with Snowflake without the app. We recommend replacing the app now and not waiting for a v2 upgrade, because the app is due to be removed in November 2026 while v1 has no comparable deadline. dbt Labs says it is open to adjusting dates, so contact your account team or support@dbtlabs.com early if you need more time. Our comparison of Snowflake Semantic Views and the dbt Semantic Layer covers the alternatives.
Roll out one project at a time, and check outputs as well as exit codes
A gradual move is possible because dbt v1 can read the v12 manifest that v2 writes, so state:modified, --defer and cross-environment docs work across mixed environments. dbt Labs suggests starting with smaller, newer or better-understood projects.
- Upgrade development first. On the dbt platform, the Debug on dbt v2 menu offers Debug in Studio, which opens the Studio IDE on v2 in your development environment, and Run once on dbt v2, which runs the job once on v2 in its usual deployment environment without changing other jobs or environment settings. We recommend trying Run once on a test job first, because on a production job the run uses that job's production environment.
- Test against production data without writing to production. We recommend adapting dbt Labs' pattern for v1 version upgrades: an upgrade project connected to the production repository, a
dbt-version-upgradebranch and a temporary environment on v2 Stable that replicates a production job. Point that environment at a zero-copy clone of production (CREATE DATABASE analytics_v2_test CLONE analytics;) under its own target name. Run the same job on v1 against a second clone so incremental models start from the same state, and check that naming overrides don't send either run to production schemas. - Decide how you would go back before you switch production. dbt Projects on Snowflake can return to a 1.x
DBT_VERSION, and self-hosted teams can install v2 in a separate environment and keep the v1 install, as dbt Labs advises. On the dbt platform, Enterprise+ Revert to Fallback moves to an older v2 build, and dbt Labs doesn't document a return to v1, so we recommend keeping production on v1 until the checks below pass.
A successful v2 run hasn't necessarily produced v1's data. In a Snowflake microbatch bug (dbt-labs/dbt#14525, opened in April 2026 and fixed by a change merged on 20 May 2026), v2 wrote each batch's source-side read filter without a UTC offset and the matching delete with one. In Snowflake sessions whose TIMEZONE wasn't UTC, the two could resolve to different time windows, which the issue notes could produce incorrect incremental results. In an earlier bug, dbt-labs/dbt#13256 (closed on 25 February 2026), v2 ignored dispatched versions of generate_schema_name, so a custom schema-naming macro supplied through dispatch, for example from a central package, was not applied. Both are fixed. Also confirm that every upstream of a microbatch model sets event_time, because without it both engines read the whole source for every batch. Then compare these.
- Row counts for every model, and the rows added by each incremental run, against the same run on v1.
- The database and schema of every built object, especially if you override schema or alias naming.
- Test results, including warnings.
- Run time and warehouse credits, because v2 manages Snowflake parallelism itself.
Keep dbt State off for these comparison runs, because skipped or cloned models would hide real differences. Our article on modelling MRR in dbt includes business-rule tests of the kind that catch a silent change in a number.
Is dbt State worth turning on?
dbt State, generally available since September 2026, skips or clones models whose logic and upstream data haven't changed and reuses earlier test results. It always rebuilds Python models, custom materialisations and views that select * straight from a ref() or source(). Clones can come from any environment with the freshest copy, CI and development schemas included, so set allow_clones: false where that isn't acceptable. State is built into dbt v2 and the platform, will be in dbt 1.13 (in beta on 24 October 2026) and runs as a plugin on 1.7 to 1.12. Every route needs a dbt platform account, though not a paid plan.
In a self-managed deployment, State also makes state:* selectors compare each node with its own last execution in the deferral target unless you pass a state manifest. That mode is still in beta, so if CI relies on state:modified, move to v2 before trying State.
As of 24 October 2026, dbt Labs' list price is USD 0.094 per daily active target table (DATT), from its Service Consumption Table effective 1 July 2026, before any contract discount. It is one USD rate billed by dbt Labs, with no Snowflake regional pricing. A DATT is each distinct table or test that State skips, clones or reuses on a UTC day, so a model with two tests counts as three. Monthly allowances are 1,000 on the self-hosted free and Developer plans, and 1,000 on Starter and 2,000 on Enterprise until 31 March 2027. The count is daily, so 200 reused tables a day come to about 6,000 DATT a month, roughly USD 376 at list price beyond an Enterprise allowance. At the limit, free and Developer accounts stop reusing nodes, Starter accounts with a card on file are billed, and Enterprise accounts draw from a prepaid State contract; without a card or contract, reuse pauses.
Eligible new organisations get a 30-day trial with no usage limit that can't be paused, so start it when a v2 project is ready to measure. Otherwise, we recommend trying State on one project within the allowance.
dbt Labs' quoted average saving of 15% to 30% or more in warehouse compute is a vendor claim. To measure, compare credits with a normal week and run dbt state explain (dbt-state explain on the v1 plugin) to see why each node was rebuilt or reused. During a trial every DATT is counted as free. To estimate the later bill, take the count from the DATT chart on the State tab under Account settings > Billing & Usage > Usage-based features, subtract your plan's monthly allowance and multiply the remainder by USD 0.094.
lag_tolerance, 45 minutes by default, is the minimum time between rebuilds of a node. A node rebuilds only when its last build is older than that and upstream data has changed since, so a longer tolerance lowers cost and leaves tables staler.
Related Articles
Frequently Asked Questions
Q: Is dbt v2 generally available?
Yes. dbt v2.0.0 was released on 14 September 2026 and announced as generally available at dbt Summit (15 to 18 September 2026), with Snowflake, BigQuery, Databricks and Redshift adapters generally available.
Q: Do I have to upgrade from dbt v1 to dbt v2?
Not yet. dbt Labs says dbt v1 remains fully supported, although over time new capabilities will be added to v2 only.
Q: What breaks when upgrading to dbt v2?
Most failures come from patterns that v1 accepted. Misspelled configs and unknown YAML keys become parse errors, calls to missing macros fail at parse time and --models and -m are rejected. Clearing deprecations on dbt 1.12 with dbt-autofix removes most of these.
Q: Does dbt v2 support Snowflake key pair authentication?
Yes, with PKCS#8 keys, and dbt recommends AES-256 encryption; 3DES-encrypted, headerless and PKCS#1 keys aren't supported. Converting an existing key with openssl pkcs8 -topk8 -v2 aes-256-cbc keeps the same key pair. A new key generated with the documented openssl command needs its public key assigned to the Snowflake user before dbt connects.
Q: Can dbt v1 and dbt v2 run side by side?
Yes. dbt v1 can read the v12 manifest that dbt v2 writes, so state:modified and --defer work across mixed environments and you can move one project at a time.
Q: How do I move a dbt Projects on Snowflake project to dbt v2?
SELECT SYSTEM$SUPPORTED_DBT_VERSIONS() lists the versions on offer, including dbt 2.0.0. Try a single run with the DBT_VERSION argument of EXECUTE DBT PROJECT, then pin the project with ALTER DBT PROJECT and SET DBT_VERSION.
Q: How much does dbt State cost?
As of 24 October 2026, dbt Labs' list price is USD 0.094 per daily active target table, meaning each distinct table or test that dbt State skips, clones or reuses on a UTC day. The self-hosted free and Developer plans include 1,000 a month with no end date, while Starter includes 1,000 and Enterprise plans 2,000 a month until 31 March 2027. Eligible new organisations get a 30-day trial without usage limits.
Q: What happens to the dbt Snowflake Native App?
It entered maintenance mode in July 2026 and is due to be removed in November 2026. dbt Labs points users to the dbt Semantic Layer and says it is open to adjusting dates for customers who need more time.
