Every time series in the Semantic Layer is grouped by metric_time plus a grain: metric_time__month,
metric_time__quarter, metric_time__year. The name is the same for every metric, which is what lets
orders, signups and balances share one axis even though each is counted by its own date.
Copy and paste
dbt sl query --metrics revenue --group-by metric_time__month --order-by metric_time__month
dbt sl query --metrics revenue,order_count,signups --group-by metric_time__quarter
dbt sl query --metrics revenue --group-by metric_time__year,customer__country --order-by metric_time__year,-revenue
With dbt Core and MetricFlow, use mf query and --order instead of --order-by.
metric_time__quarter revenue order_count signups
---------------------- --------- ------------- ---------
2025-01-01T00:00:00 310 3 3
2025-04-01T00:00:00 340 4 1
2025-07-01T00:00:00 200 2
2025-10-01T00:00:00 490 3
2026-01-01T00:00:00 340 3 2
2026-04-01T00:00:00 550 4
The grains
day, week, month, quarter and year, plus finer ones (hour, minute…) if the time dimension
has them, and any custom granularity
of the time spine, such as metric_time__fiscal_year. A grain can’t be finer than the column’s
granularity.
metric_time without a grain uses the finest grain available, a day here. Each period is labelled by its
first moment: 2025-04-01T00:00:00 is the second quarter of 2025. Format it in the BI tool.
One timeline for several metrics
In the quarterly output, revenue and order_count are grouped by order date and signups by signup
date, because metric_time means each metric’s own default time dimension.
Empty cells are periods in which a metric has no data; the results are combined with a full outer join, so
no period is lost.
Another date of the same model
order__order_date__month and order__shipped_date__month group by a named time dimension instead. They
work for metrics of that model and of the models it joins, but not across unrelated metrics, and
features that rely on metric_time (cumulative metrics, offsets, --start-time) keep using the metric’s
own date.
Several grains at once
mf query --metrics revenue --group-by metric_time__year,metric_time__month --start-time 2026-03-01
metric_time__month metric_time__year revenue
-------------------- ------------------- ---------
2026-03-01T00:00:00 2026-01-01T00:00:00 100
2026-04-01T00:00:00 2026-01-01T00:00:00 80
2026-05-01T00:00:00 2026-01-01T00:00:00 470
Useful for BI tools that build a year–month hierarchy from two columns.
Sorting
--order-by (--order with mf) takes a comma-separated list; a - before a name sorts descending:
metric_time__month,-revenue sorts by month, then by revenue from the highest. Without it, rows come back
in whatever order the warehouse returns them, which is often not chronological.
Month of year
Seasonality questions (“which month sells best across years?”) need the month number regardless of year.
The CLI didn’t accept metric_time__extract_month (“does not match any of the known formats”). Add a
month-number dimension to the model with
derived_semantics, or let the BI
tool extract it from the monthly series.
Tested with dbt Core 1.12 and MetricFlow 0.213 on DuckDB; the dbt sl options come from the dbt
documentation.