What you will be able to do
- Say which optional job settings inherit from the environment and which have their own job-level default
- Use a job-level environment variable override or a custom target name to change project behaviour for one job
- Choose a thread count while weighing concurrency against warehouse load
- Choose a deferral setting for a deploy job, and say when to leave the dbt version override alone
Key concept
Job-level override — A job runs inside one deployment environment and uses that environment's settings by default. Its optional Advanced settings let you change a few of them for that job only, without touching the environment or any other job in it.
1.Where a job's optional settings live
Every dbt job has an optional Advanced settings section. A job can run without touching it. You go there when one job needs to behave differently from the environment it runs in. On a deploy job the section lists Environment variables, Target name, Run timeout, Compare changes against, dbt version and Threads. Run timeout cancels the job if its run time exceeds the value you set. The other five each either override something the environment already defines or set a job-specific default.
The defaults show how dbt expects you to use them. With no changes, a job inherits the environment's dbt version, uses 4 threads and defers to nothing. Environment variables inherit the values set at the environment (or project) level until you override them on the job, while target name has no job-level value until you add one. Each change applies to that single job. A second job in the same environment keeps the environment's values unless it sets its own.
| Setting | Default | Change it when |
|---|---|---|
| Environment variables | Inherits environment (or project) values | One job needs a different value than others in the same environment |
| Target name | None set on the job | Project code branches on target.name and this job needs its own branch |
| Run timeout | Set per job | A run that exceeds the timeout value should be cancelled |
| Threads | 4 threads | You want more model execution concurrency and the warehouse can take the load |
| Compare changes against | No deferral | The job should compare against an Environment or This Job |
| dbt version | Inherit from the environment | Only while upgrading a project to the next dbt version |
CI jobs have a similar Advanced settings section with environment variables, target name, dbt version and threads, plus a Run source freshness toggle. On a CI job, deferral is configured as part of the setup covered in [CI jobs with deferral](lesson:4.1). Everything below applies to both job types unless it says otherwise.
Checkpoint 1 of 9· Check yourself
You create a deploy job and never open Advanced settings. Which description of how it runs is correct?
The dbt version is inherited from the environment, threads default to 4, and Compare changes against defaults to No deferral.
“By default, it’s set to inherit the dbt version from the environment.”Source: docs.getdbt.com
2.Environment variable overrides and precedence
A job-level environment variable override exists because several jobs can share one environment. Take a nightly full build and an hourly incremental job, both in Production. If they should read a different DBT_ variable, the environment level can't separate them, because it holds one value per environment. When you set up or edit a job, you can override values already defined at the environment or project level, so the variable has to exist there first; the new value applies to that job only. How these variables are named and set is covered in [environment variables](lesson:3.4). What matters here is which value wins.
dbt resolves an environment variable through four levels, from lowest to highest precedence:
1. The optional default argument in the env_var Jinja call in your code
2. The project-wide default
3. The environment level
4. The job override (or, in the Studio IDE, a developer's personal override)
The job override is at the top, so it beats everything below it. When a job runs with an unexpected value, check the job's overrides before the environment's.
The project default and environment values are set in one place: click Orchestration in the left-side menu, select Environments, then click Environment variables. The Project default column holds a catch-all value for the whole project, and each environment has its own column to the right that takes priority over it.
CI is the most common use. Many teams process only a subset of data in CI by setting a variable on the CI job and branching on it in project code. Production jobs never see that variable, so the same models run in full there.
Checkpoint 2 of 9· Put it in order
Order these places an environment variable can be set, from lowest to highest precedence.
- 1.Default argument passed to env_var in code
- 2.Environment level
- 3.Project default
- 4.Job override
Each level can be overridden by the one after it, and the job override (or personal override in the IDE) has the highest precedence.
“The job level (job override) or in the Studio IDE for an individual dev (personal override). (highest precedence)”Source: docs.getdbt.com
Checkpoint 3 of 9· Exam question
A dbt Cloud project has one Production environment but two deploy jobs that must run against different Snowflake warehouse sizes: a nightly full-refresh job needs an XL warehouse, and an hourly incremental job needs a medium warehouse. Both jobs reference `{{ env_var('DBT_WAREHOUSE') }}` in the connection config. Without creating a second environment, how should the team make each job resolve `DBT_WAREHOUSE` to its own warehouse size?
Correct answer: A — Set an environment variable override for `DBT_WAREHOUSE` on each job individually, since a job-level override takes precedence over the environment-level value for that job's runs.
- A. A job-level environment variable override sits above the environment-level value in dbt Cloud's resolution order, so each job can carry its own `DBT_WAREHOUSE` value while sharing the same Production environment.
- B. An environment-level value is a single value shared by every job that runs in that environment; it does not vary automatically per job, so both jobs would resolve the same warehouse size.
- C. The `env_var()` default argument is only a fallback used when no other value is set anywhere else, and it is baked into project code rather than something a job can toggle per run, so it cannot supply two different live values.
- D. Duplicating environments works but forces the team to keep every other environment-scoped setting, such as custom branch and credentials, synchronized across the copies; a job-level override achieves the same split without that duplication.
3.Custom target name
The Target name field sets the value your project sees as target.name when this job runs. It is useful whenever models contain Jinja that branches on the target. A common case is limiting how much data a model reads outside production. You set it in the Target Name field on the job's Job Settings page. Developers set their own target name in their user credentials, so the same project code can take a different branch in development, CI and production.
Target name and environment variables overlap in purpose: both let project code decide how to behave based on where it is running, and the CI documentation describes either one as a way to flag a CI job. They are still different mechanisms. Target name is one built-in value your code reads through target.name. Environment variables are separate keys that you read with env_var, and you can define as many as you need.
Checkpoint 4 of 9· Fill the gap
This model should scan only the current month everywhere except production. Which variable completes the condition?
select *
from a_big_table
-- limit the amount of data queried in dev
{% if ? != 'prod' %}
where created_at > date_trunc('month', current_date)
{% endif %}The job's Target name field sets target.name. A job whose target name is not 'prod' gets the date filter, and a job with target name 'prod' reads the whole table.
Source: docs.getdbt.comCheckpoint 5 of 9· Exam question
A dbt Cloud CI job runs against pull requests, and the team wants model code to apply CI-only logic — for example, excluding a long-running data quality test that only makes sense once code is merged — by checking a value in Jinja like `{{ target.name == 'ci' }}`. Which Advanced setting on the CI job should the team configure to make that value available?
Correct answer: A — Set the job's Target Name to a distinguishing value such as `ci`, since target name is exposed to project code as `target.name` and can be branched on directly.
- A. The Target Name field in a job's Advanced settings is exactly what `target.name` resolves to in project code, so setting it to a distinct value like `ci` is the direct way to branch model logic for that job.
- B. `DBT_CLOUD_ENVIRONMENT_TYPE` is a pre-defined platform variable that dbt Cloud sets automatically to dev, staging, or prod; it cannot be reassigned by a job-level override, so this would not produce a usable CI signal.
- C. Deferral controls which prior run's state a job compares against for unmodified-model detection; it has no effect on what `target.name` resolves to for the current job's models.
- D. Threads control how many models a job builds concurrently and have no relationship to which target profile or `target.name` value the job resolves.
4.Threads and concurrency
Threads set how many models dbt can build at once. dbt builds a DAG of your models, and the thread count is the maximum number of paths through that graph it works on at the same time. With 1 thread, dbt finishes each model before it starts the next. A job defaults to 4 threads, and raising the number increases model execution concurrency. There is no set upper limit.
More threads do not always mean a faster run. The DAG sets the first limit: dbt never breaks dependencies, so a long chain of dependent models runs one after another however many threads are free. The warehouse sets the second. More threads mean more load, and that can slow other tools on the same compute. If your BI tool shares the warehouse, its queries may queue during a dbt run. The database's limit on concurrent queries also caps how many models can run at once, and extra models wait for a free query slot. The best number depends on the warehouse, so test a few values.
dbt v2 treats threads differently. There a thread is an open connection to the warehouse, and setting threads to 256 in a dbt platform job lets dbt run as many queries at once as the project allows. That advice does not suit every warehouse: on Snowflake and Databricks, dbt v2 manages connection parallelism itself and treats threads only as an optional maximum cap, lowering it only if you hit timeouts or rate limits.
Checkpoint 6 of 9· Check yourself
A team raises a job from 4 to 32 threads, but the run time barely changes and dashboards slow down during the run. Which explanation fits?
Threads set a maximum. Available DAG paths and warehouse query slots decide how much really runs in parallel, and the extra load can queue other tools' queries.
“Increasing the number of threads increases the load on your warehouse, which may impact other tools in your data stack.”Source: docs.getdbt.com
5.Deferral in a job: Compare changes against
Deferral lets a run build only what changed without first building everything upstream. dbt compares the project against a saved state, and when a model the run did not build is referenced, ref resolves to that model's location in the compared state instead of an empty schema. That saves time and warehouse compute in a large project. The saved state is the manifest.json, the record of the project's models that each run produces.
Deferral is off until you turn it on. Compare changes against starts at No deferral. Choosing Environment or This Job gives dbt the previous state to compare the job's changes against. The environment-level setup this depends on is covered in [deferral to other environments](lesson:3.8).
When you can, choose an environment over a job. Deferring to a job compares state only against the code from that job's last successful run. Deferring to an environment compares against the manifest from the last successful deploy job run in that environment, whichever deploy job it was. Because dbt considers every deploy job in the environment, it gets a more accurate and up-to-date view of the project. Older dbt versions only allowed deferral to a specific job. This Job makes the job compare against its own previous run, which is covered in [self-deferral](lesson:4.10). [Choosing between deferral types](lesson:4.11) has its own lesson.
Checkpoint 7 of 9· Check yourself
Three deploy jobs run in Production at different times. A new job should compare against the most current state of the project. Which setting fits best?
Environment deferral uses the manifest from the last successful deploy job run in that environment, whichever job it was. Job deferral sees only one job's last run.
“By considering all deploy jobs that run in the deferred environment, dbt will get a more accurate, latest project representation state.”Source: docs.getdbt.com
Checkpoint 8 of 9· Exam question
A CI job is configured to defer to 'This Job (self)'. After a pull request merges and its CI schema is torn down, the next PR's CI run against the same branch pattern fails with errors referencing tables from the already-merged PR's schema. What is the most likely cause, and what should the team change?
Correct answer: A — The job compares against its own last successful run, whose schema no longer exists after the merge; point deferral at Production instead of self.
- A. Self-deferral compares against that same job's most recent successful run; once the merged PR's ephemeral schema is dropped, the next run has nothing valid to defer to, so pointing deferral at Production (or a job in it) fixes the stale reference.
- B. A dbt version mismatch produces version-compatibility warnings or behavior differences, not errors about a dropped schema from a prior PR, so this is not the cause of the described failure.
- C. Thread count governs in-run model concurrency for the current run; it has no bearing on whether a previously merged PR's schema still exists for deferral purposes.
- D. Target name customizes `target.name` for project logic branching; it is not what determines which prior run's schema a deferred build reads from, so renaming it would not resolve the missing-schema error.
6.dbt version override
Jobs and environments each have a dbt version, but a job should normally inherit the environment's. dbt Labs strongly recommends keeping that default. A job-level version override has one intended use: upgrading a project to the next dbt version, for example by running one job on the new version before you move the whole environment. Any other mismatch between job and environment can cause confusing behavior. Code compiles one way during development and another way when the job runs.
Developers have a separate override in their own credentials. It changes the version for that user only, so they can test the project on a newer version before deployment environments are upgraded. After the upgrade is tested, change the version on the environment and remove any job-level overrides so the job inherits again.
Checkpoint 9 of 9· Check yourself
A deploy job's dbt version is set to a different release than its environment, and nobody remembers why. No upgrade is underway. What is the recommended action?
The job-level version override is only for upgrading a project. Outside an upgrade, a mismatch between job and environment leads to confusing behavior.
“mismatched versions between the environment and job can lead to confusing behavior”Source: docs.getdbt.com
Exam traps
Each one states something that sounds right. Open it to see what is actually true.
1.Overriding an environment variable on a job changes it for every job in that environment.Why is that wrong?
A job override applies only to that job. Other jobs in the environment keep the environment-level value, which is why the job level exists.
2.A deploy job defers to the production environment by default.Why is that wrong?
Compare changes against defaults to No deferral. You have to choose Environment or This Job yourself.
Covered in Deferral in a job: Compare changes against
3.The job-level dbt version is a normal setting to change whenever one job needs newer features.Why is that wrong?
dbt Labs strongly recommends keeping the inherited version. The override is meant only for upgrading a project to the next dbt version.
Covered in dbt version override
4.Doubling threads halves run time.Why is that wrong?
Threads set a maximum. Available paths in the dependency graph and the warehouse's concurrent-query limit decide how many models really run at once.
Covered in Threads and concurrency
Sources
Every claim above is drawn from one of these pages, quoted as it was written on the date shown.
- 1.https://docs.getdbt.com/docs/deploy/deploy-jobsOfficial docs
“Define environment variables to customize the behavior of your project when the deploy job runs.”
↩︎ Where a job's optional settings live“Cancel the deploy job if the run time exceeds the timeout value.”
↩︎ Where a job's optional settings live“Environment variables and target names are often used interchangeably.”
↩︎ Custom target name“Increase the thread count to increase model execution concurrency.”
↩︎ Threads and concurrency“Deferral to a job compares state against the project code that was run in the deferred job's last successful run.”
↩︎ Deferral in a job: Compare changes against“deferral to an environment is more efficient as dbt will compare against the project representation (which is stored in the manifest.json)”
↩︎ Deferral in a job: Compare changes against“dbt Labs strongly recommends that you don't change the default setting.”
↩︎ dbt version override“set to No deferral. Select either Environment or This Job to let dbt know what it should compare the changes against.”
↩︎ Exam trap 2“dbt Labs strongly recommends that you don't change the default setting.”
↩︎ Exam trap 3“By default, it’s set to inherit the dbt version from the environment.”
↩︎ Checkpoint“set to No deferral. Select either Environment or This Job to let dbt know what it should compare the changes against.”
↩︎ Prediction“By considering all deploy jobs that run in the deferred environment, dbt will get a more accurate, latest project representation state.”
↩︎ Checkpoint“mismatched versions between the environment and job can lead to confusing behavior”
↩︎ Checkpoint - 2.https://docs.getdbt.com/docs/deploy/ci-jobsOfficial docs
“Enable this option to invoke the dbt source freshness command before running this CI job.”
↩︎ Where a job's optional settings live“process only a subset of data for CI runs, using environment variables to branch logic in their dbt project code”
↩︎ Environment variable overrides and precedence“You can use this option to specify that a CI job is running in a Staging or CI environment by setting the target name”
↩︎ Custom target name - 3.
“You may have multiple jobs that run in the same environment”
↩︎ Environment variable overrides and precedence“The optional default argument supplied to the env_var Jinja function in code, which can be overridden at (lowest precedence)”
↩︎ Environment variable overrides and precedence“To set environment variables at the project and environment level, click Orchestration in the left-side menu, then select Environments.”
↩︎ Environment variable overrides and precedence“you will see a section where you can override environment variable values defined at the environment or project level”
↩︎ Environment variable overrides and precedence“Every job runs in a specific deployment environment, and by default, a job will inherit the values set at the environment level”
↩︎ Key concept“If you'd like to set a different value at the job level, edit the value to override it.”
↩︎ Exam trap 1“The job level (job override) or in the Studio IDE for an individual dev (personal override). (highest precedence)”
↩︎ Checkpoint - 4.
“To set a custom target name for a job in dbt, configure the Target Name field for your job in the Job Settings page.”
↩︎ Custom target name“When developing in dbt, you can set a custom target name in your user credentials.”
↩︎ Custom target name - 5.
“The number of threads represents the maximum number of paths through the graph dbt may work on at once”
↩︎ Threads and concurrency“concurrent queries your database will allow you to run may be a limiting factor”
↩︎ Threads and concurrency“There's no set limit of the maximum number of threads you can set”
↩︎ Threads and concurrency“In the context of dbt v2, a thread is an open connection to your data warehouse”
↩︎ Threads and concurrency“When running in dbt platform: Set threads to 256 in your job settings.”
↩︎ Threads and concurrency“dbt v2 automatically manages connection parallelism based on platform limits and backpressure.”
↩︎ Threads and concurrency“the actual number of models it can work on will likely be constrained by the available paths through the dependency graph”
↩︎ Exam trap 4“Increasing the number of threads increases the load on your warehouse, which may impact other tools in your data stack.”
↩︎ Checkpoint - 6.
“This can save time and computational resources when you want to test a small number of models in a large project.”
↩︎ Deferral in a job: Compare changes against“dbt will resolve all instances of {{ ref('model_a') }} to prod.model_a instead.”
↩︎ Deferral in a job: Compare changes against - 7.
“In dbt, both jobs and environments are configured to use a specific version of dbt.”
↩︎ dbt version override“use the Override dbt version setting to test your project on the latest dbt version before upgrading your deployment environments”
↩︎ dbt version override