dbt's var() is a runtime parameter resolved at Jinja compile time. Use it to flexibly switch model and macro branching, thresholds, and date boundaries.
This article organizes variable precedence, design principles, concrete implementations, validation, and operations from both an exam (dbt Analytics Engineer) and a real-world perspective.
var('name', default) is a variable reference resolved at Jinja compile time. Without a default, a missing variable produces a compile error. With a default, the build continues using that explicit fallback value when the variable is not set.
Variables are mainly set in the vars block of dbt_project.yml or via the CLI --vars flag. If the same key exists in both places, the CLI value wins. When a package references var(), you can override it by placing a value under the package's namespace in the root project's dbt_project.yml.
| Location | Example | Priority | Typical use |
|---|---|---|---|
| CLI --vars | dbt run --vars "{start_date: '2024-01-01', use_new_logic: true}" | Highest | Temporary overrides, CI/CD switching |
| dbt_project.yml vars (root) | vars:\n start_date: '2021-01-01'\n use_new_logic: false | Medium | Centralized defaults and team-wide standards |
| Package variable override | vars:\n some_package:\n enable_feature: true | Medium (scoped to the target package) | Overriding default behavior of external packages |
| var()'s default | {{ var('start_date', '1900-01-01') }} | Lowest | Safe fallback that avoids compile errors |
Variables should be "minimal and explicit." Limit runtime parameterization to thresholds and switches you want to change frequently without a redeploy. Too many variables explode the test matrix.
Types and naming directly affect long-term maintainability. Be explicit about types (booleans, dates, numbers, enums) and set defaults to safe, testable, least-privilege values.
Below is a minimal example that defines defaults in dbt_project.yml and uses var() inside a model to toggle conditional logic and date boundaries. CI overrides them temporarily via CLI --vars.
When embedding date literals in SQL, quote and cast appropriately for your dialect (TO_DATE on Snowflake, DATE() on Databricks, etc.).
Example linking dbt_project.yml, the model, and the CLI
# dbt_project.yml(抜粋)\nname: my_project\nversion: 1.0.0\nconfig-version: 2\n\nvars:\n start_date: '2021-01-01'\n use_new_logic: false\n\nmodels:\n my_project: {+materialized: table}\n\n---\n-- models/fct_orders.sql(抜粋)\n{{ config(materialized='table') }}\n\nwith src as (\n select * from {{ ref('stg_orders') }}\n {% if var('use_new_logic', false) %}\n where updated_at >= '{{ var('start_date', '1900-01-01') }}'\n {% endif %}\n)\n\nselect * from src\n\n---\n# 一時的に上書き(CI など)\n# Linux/macOS の例(シェルでクォートに注意)\ndbt build --vars "{use_new_logic: true, start_date: '2024-01-01'}"When an external package (e.g., dbt-utils) references var(), you can override its behavior by creating a namespace named after the package in the root project's dbt_project.yml and defining keys underneath it.
This is the standard, safe way to change a package's default behavior. Record any overrides in the README so you can review diffs when upgrading the package.
Example of overriding package variables (dbt_project.yml)
vars:\n some_package:\n enable_feature: true\n threshold: 10For important variables, validating allowed values at compile time is safer. It fails fast when unexpected values slip in and prevents incorrect SQL from running. In dbt you can fail explicitly with exceptions.raise_compiler_error.
Jinja truthiness follows Python, so a non-empty string like "false" evaluates as truthy. Always pass booleans as the boolean type, and on the CLI quote them so that true/false are interpreted as YAML.
Example macro that guards at compile time
{% macro require_valid_choice(var_name, allowed) %}\n {% set value = var(var_name, none) %}\n {% if value is none or value not in allowed %}\n {{ exceptions.raise_compiler_error(var_name ~ ' must be one of ' ~ (allowed | join(', ')) ~ ', but was: ' ~ (value|string)) }}\n {% endif %}\n{% endmacro %}\n\n-- 利用例(モデル先頭など)\n{{ require_valid_choice('region', ['us', 'eu', 'ap']) }}Handle behavior differences across environments (dev/stg/prod) primarily through connection profiles and target, and use var only for the parts of business logic that should vary. In CI, validate the main combinations via --vars.
The diagram below illustrates the var resolution flow. CLI wins if present; otherwise dbt_project.yml is consulted; finally the default is used, and the resolved value lands in the compiled SQL.
var resolution flow (precedence and propagation path)
Example for GitHub Actions (verifying the key flag in both states)
jobs:\n build:\n runs-on: ubuntu-latest\n steps:\n - uses: actions/checkout@v4\n - uses: actions/setup-python@v5\n with: { python-version: '3.11' }\n - run: pip install dbt-core dbt-snowflake\n - name: Build (use_new_logic=false)\n run: dbt build --vars "{use_new_logic: false, start_date: '2021-01-01'}"\n - name: Build (use_new_logic=true)\n run: dbt build --vars "{use_new_logic: true, start_date: '2024-01-01'}"Analytics Engineer
問題 1
A model references {{ var('start_date', '1900-01-01') }}. dbt_project.yml sets start_date: '2021-01-01', and at runtime you pass dbt run --vars "{start_date: '2022-01-01'}". Which value is actually used?
正解: C
var precedence is CLI --vars > dbt_project.yml vars > var()'s default. Therefore '2022-01-01' is used.
What is the difference between vars and env_var, and which should I use?
vars handle runtime parameters for business logic (flags, thresholds) and are configured in dbt_project.yml or via CLI --vars. env_var is a function that reads environment variables and is the right choice for sensitive values like credentials, secrets, and connection targets. Use env_var, not vars, for sensitive data.
Can I put vars in profiles.yml?
No. vars are managed in the vars block of dbt_project.yml and via CLI --vars. profiles.yml is where you define connection information (account, user, role, warehouse, etc.) and should not contain business-logic parameters.
How are --vars values typed?
They are parsed as YAML/JSON. true/false are booleans, numerics are numbers, and strings must be quoted. Example: dbt run --vars "{use_new_logic: true, threshold: 10, start_date: '2024-01-01'}". Be careful: passing the string 'false' is evaluated as truthy.
Practice with certification-focused question sets
無料で問題を解いてみるNicheeLab Editorial Team
NicheeLab editorial team focused on data engineering and cloud certification learning. Content is structured around practical study needs and official exam domains.
dbt Models: SQL-Defined Transformation Units (2026)
Model fundamentals — SELECT-based definitions, naming, refs,...
dbt Analytics Engineering Exam: Complete Guide (2026)
Pass the AE Certification — scope, weighting, sample questio...
dbt Cloud vs dbt Core: Feature & Cost Comparison (2026)
Honest comparison of dbt Cloud vs. dbt Core — IDE, scheduler...
dbt Project Structure: models/seeds/macros Layout (2026)
Recommended dbt project layout — models, seeds, macros, snap...
dbt_project.yml Explained: Every Config (2026)
Every dbt_project.yml setting that matters — paths, vars, ma...