Freshness thresholds and loaded_at_field are already set on every source, and the nightly job builds all models. You want the next job run to build only the models downstream of sources whose maximum loaded_at_field timestamp advanced since the previous freshness check. Arrange the steps. Two steps in the pool do not belong.
In the exam you drag the steps into order. The correct sequence is below.
- 1Run dbt source freshness, which writes the current freshness result to target/sources.json
- 2Copy that target/sources.json into prod-artifacts/ so the next run has a previous state to compare against
- 3On the next job run, run dbt source freshness again to write a new target/sources.json
- 4With both artifacts in place, run dbt build --select "source_status:fresher+" --state prod-artifacts
- Run dbt compile to regenerate target/sources.json before the comparison
- Run dbt build --select "state:modified+" --state prod-artifacts to pick up the newly loaded rows
WHY
source_status:fresher+ is a state-based selector, so it needs TWO sources.json artifacts: a saved previous one and the current one. The chain is forced by which file exists when. Step 1 produces the first artifact — /reference/commands/source: "When dbt source freshness completes, a JSON file containing information about the freshness of your sources will be saved to target/sources.json." Step 2 must copy that file out of target/ before anything overwrites it, because the next freshness run writes to the same path; with nothing in prod-artifacts/ there is no previous state and the selector has nothing to compare. Step 3 then runs the check again to produce the current max_loaded_at values — /reference/node-selection/methods shows exactly this pairing for dbt v1.11: "dbt source freshness # must be run again to compare current to previous state" followed by "dbt build --select \"source_status:fresher+\" --state path/to/prod/artifacts". Only then does step 4 work: dbt compares max_loaded_at per source ("Max value of loaded_at_field timestamp in the source table when queried", /reference/artifacts/sources-json) between the two files, selects the sources whose value moved forward, and the trailing + pulls in everything downstream of them. Flags follow the subcommand, which is the current supported placement. Precision on what fresher means: sources.json records max_loaded_at — the maximum loaded_at_field value in the source table when queried (https://docs.getdbt.com/reference/artifacts/sources-json) — so source_status:fresher selects sources whose recorded maximum advanced between the two snapshots; late-arriving rows with older loaded_at values do not move it.
WHY THE OTHERS ARE WRONG
- Run dbt compile to regenerate target/sources.json before the comparison
- dbt compile does not produce a sources.json. The methods page names the only source of that artifact — "The following dbt commands produce sources.json artifacts whose results can be referenced in subsequent dbt invocations: dbt source freshness" — and /reference/artifacts/sources-json lists it as "Produced by: source freshness". compile writes manifest.json, so this step leaves the state directory without the file source_status needs.
- Run dbt build --select "state:modified+" --state prod-artifacts to pick up the newly loaded rows
- state:modified compares project code, not load times: "The state method is used to select nodes by comparing them against a previous version of the same project, which is represented by a manifest", and "state:modified: All new nodes, plus any changes to existing nodes." A vendor loading fresh rows changes no node in the project, so this selector matches nothing here and the job builds nothing.