A daily model usually loads the day that has just ended. You can compute that date in SQL, where the warehouse decides what “today” is, or in Jinja, where dbt fixes it once for the whole run. The second option also lets you replace the date when you rerun an old day.
Copy and paste
In SQL (Snowflake):
where order_date = dateadd(day, -1, current_date)
In Jinja, fixed for the whole run (UTC):
where order_date = '{{ (run_started_at - modules.datetime.timedelta(days=1)).strftime("%Y-%m-%d") }}'
In Jinja, in your timezone:
where order_date = '{{ (run_started_at.astimezone(modules.pytz.timezone("Europe/Rome")) - modules.datetime.timedelta(days=1)).strftime("%Y-%m-%d") }}'
With an override for reruns:
{%- set yesterday = (run_started_at - modules.datetime.timedelta(days=1)).strftime("%Y-%m-%d") -%}
select *
from {{ ref('stg_orders') }}
where order_date = '{{ var("run_date", yesterday) }}'
dbt run -s orders_daily # yesterday
dbt run -s orders_daily --vars '{run_date: "2026-05-14"}' # a day of your choice
As a macro, to use in many models:
-- macros/yesterday.sql
{% macro yesterday(tz='UTC') -%}
{{ return((run_started_at.astimezone(modules.pytz.timezone(tz)) - modules.datetime.timedelta(days=1)).strftime('%Y-%m-%d')) }}
{%- endmacro %}
where order_date = '{{ yesterday('Europe/Rome') }}'
SQL or Jinja
dateadd(day, -1, current_date) |
run_started_at in Jinja |
|
|---|---|---|
| Evaluated | by the warehouse, when each query runs | by dbt, once at the start of the run |
| Timezone | the session’s TIMEZONE; on Snowflake the default is America/Los_Angeles |
UTC, unless you convert it |
| Same value in every model | only if the run does not cross midnight | yes |
| Can be replaced for a rerun | no | yes, with var() |
The Snowflake default deserves attention: unless your account or user sets TIMEZONE, current_date
is the date in California. Between midnight and 09:00 in Rome, it is still the previous day there, so
“yesterday” in SQL is two days ago for you.
What run_started_at contains
run_started_at is the moment the dbt command started, in UTC, as a Python datetime:
run_started_at 2026-10-27 08:27:24.772148+00:00
today (UTC) 2026-10-27
yesterday (UTC) 2026-10-26
Every model in the run sees the same value, even if the run lasts past midnight. modules.datetime
and modules.pytz give access to the Python modules of the same names inside Jinja.
When a scheduler passes the date
If Airflow or another scheduler starts dbt, let it pass the date with --vars, and keep the Jinja
default only for runs started by hand. The scheduler knows which day each run belongs to, also when it
reruns an old one; see
how to get yesterday’s date in an Airflow task.
The Jinja was tested with dbt Core 1.12; the SQL is written for Snowflake.