Docs / Build Workflow

Filter — cutoff_date

When to use cutoff_date

Use cutoff_date when the analysis is "everything from the start of the month up to a chosen day" — month-to-date revenue, monthly closing reports, "as-of" snapshots. The user picks a single date; Looky automatically sends both date_from (the first day of that month) and date_to (the chosen date) as parameters.

Use date_range when the user needs to pick both endpoints freely. Use date_range_preset when the choice is among named presets like "last 30 days" or "this quarter".

Required fields

  • type: cutoff_date

Optional fields

  • id — internal identifier for the filter.
  • label — display label above the picker.
  • param — the parameter name the resolved cutoff date itself is additionally sent under (defaults to the filter's id, then to cutoff_date). The derived window always arrives as date_from / date_to regardless.
  • default — date token (see below) or ISO date string. Defaults to "{{today}}".
  • granularity — controls how date_from is derived from the chosen date. One of day, month (default), quarter, year. With day, date_from equals the chosen date (one-day window). With month, the first day of the chosen date's month. With quarter, the first day of the chosen date's calendar quarter (Jan, Apr, Jul, or Oct). With year, January 1 of the chosen date's year. Honored at both dashboard and visualization level.
  • include_current_day — boolean. Default false. See Maximum selectable date.

Maximum selectable date — today or yesterday

By default, the cutoff_date filter caps the maximum date at today − 1 day. The picker does not let the user select today, the {{today}} token resolves to today but is clamped down to yesterday, and the date_to sent to the query always lands on yesterday. This is the historical convention for "as-of yesterday's close" reports: in-progress day data is usually incomplete until end-of-day, so the report anchors to the last closed day.

For live operational dashboards — where you do want to include the in-progress day — add include_current_day: true:

filters:
  - type: cutoff_date
    label: Cutoff
    default: "{{today}}"
    include_current_day: true

With the flag on:

  • The picker allows today as the maximum selectable date.
  • {{today}} resolves to today and is not clamped.
  • The date_to sent to the query is inclusive of the current day.

The flag is opt-in (default false) to preserve back-compat with daily-report dashboards (PDFs, period closes) whose semantics expect "through yesterday's close".

When to turn it on: live operational dashboards, "what have I accrued so far" KPIs, in-progress billing, progress monitoring. When to leave it off (default): reports exported to PDF and sent as end-of-day summaries, historical snapshots, reports that need post-close consolidation.

The flag is declared independently on each filter — on the visualization (if opened standalone) and on the dashboard (if it has a global filter that propagates via param:). If the viz lives inside a dashboard with a global filter, the dashboard flag is sufficient; the resolved value reaches the viz via the param.

Date tokens for defaults

These tokens resolve against the workspace timezone (ui.timezone in workspace.yml, falling back to the instance default):

  • {{today}}
  • {{yesterday}}
  • {{start_of_week}} / {{end_of_week}}
  • {{start_of_month}} / {{end_of_month}}

Anything not in this list is treated as a literal ISO date string (e.g. "2024-12-31").

How the value reaches the Malloy query

The chosen date sets two parameters on every query that the filter applies to:

  • date_from — derived from the chosen date according to granularity (defaults to first day of its month).
  • date_to — the chosen date itself.

Your Malloy model declares those two parameters and uses them in where: clauses:

##! experimental.parameters

source: ec_orders(
  p_date_from::date is @2024-01-01,
  p_date_to::date   is @2024-12-31
) is ecommerce.table('bigquery-public-data.thelook_ecommerce.order_items') extend {
  view: revenue_mtd is {
    where:
      created_at::date >= p_date_from
      and created_at::date <= p_date_to
    aggregate:
      revenue is sum(sale_price)
  }
}

Adapter differences

Both date_from and date_to are date / timestamp parameters. On BigQuery they bind natively. On Postgres and MySQL the model must use the @param placeholder pattern in the underlying SQL — see the source adapter comparison and Malloy support.

Worked examples

Default cutoff is today:

filters:
  - type: cutoff_date
    label: Cutoff
    default: "{{today}}"

Default cutoff is end of last month (for monthly close reports):

filters:
  - type: cutoff_date
    label: Closing date
    default: "{{end_of_month}}"

Default cutoff is a literal date (for a fixed historical snapshot):

filters:
  - type: cutoff_date
    label: As of
    default: "2024-12-31"