Freshness Policies
dagster-rocky maps Rocky’s freshness configuration onto Dagster’s
FreshnessPolicy,
which says how old an asset’s data may get before Dagster calls it stale. The
Dagster UI then shows stale-data badges, and the declarative-automation
freshness conditions fire correctly.
Freshness comes from two places. A per-model setting wins over the pipeline-level one.
- Pipeline-level: from
[checks.freshness]inrocky.toml. Applies to every source-replication asset by default. - Per-model: from
[freshness]in a model’s TOML frontmatter. Overrides the pipeline-level default for the matching model.
Pipeline-level freshness
Section titled “Pipeline-level freshness”Add a [checks.freshness] block to rocky.toml:
[checks]enabled = true
[checks.freshness]threshold_seconds = 86400 # 24 hoursRockyComponent reads discover.checks.freshness and attaches a matching
FreshnessPolicy to every source-replication asset. Nothing else to configure.
Wire it up in defs.yaml:
type: dagster_rocky.RockyComponentattributes: config_path: rocky.tomlThe functional API works the same way:
from dagster_rocky import RockyResource, load_rocky_assets
rocky = RockyResource(config_path="rocky.toml")specs = load_rocky_assets(rocky)# specs[*].freshness_policy is set to FreshnessPolicy.time_window(fail_window=24h)Per-model freshness
Section titled “Per-model freshness”Declare freshness in a model’s TOML frontmatter (or sidecar .toml file):
name = "fct_daily_orders"depends_on = ["stg_orders"]
[strategy]type = "incremental"timestamp_column = "updated_at"
[target]catalog = "warehouse"schema = "marts"table = "fct_daily_orders"
[freshness]expected_lag_seconds = 3600 # 1 hour — overrides the pipeline default (max_lag_seconds is accepted as a legacy alias)rocky compile emits this in its JSON output, in the models_detail field.
RockyComponent reads it at load time. When a source-replication table name
matches a compiled model name, the per-model policy wins.
Helper functions
Section titled “Helper functions”These helpers are pure functions. Use them to attach freshness policies to
hand-rolled assets, without going through RockyComponent.
freshness_policy_from_checks(checks)
Section titled “freshness_policy_from_checks(checks)”Builds a FreshnessPolicy from a ChecksConfig, the projection of
[checks.freshness]. Returns None when freshness is not configured.
from dagster_rocky import freshness_policy_from_checks, RockyResource
rocky = RockyResource(config_path="rocky.toml")result = rocky.discover()policy = freshness_policy_from_checks(result.checks)# Use policy on AssetSpec.freshness_policyfreshness_policy_from_model(freshness)
Section titled “freshness_policy_from_model(freshness)”Builds a FreshnessPolicy from a ModelFreshnessConfig, the projection of a
model’s [freshness] frontmatter. Returns None when not configured.
from dagster_rocky import freshness_policy_from_modelfrom dagster_rocky.types import ModelFreshnessConfig
policy = freshness_policy_from_model(ModelFreshnessConfig(max_lag_seconds=3600))per_model_freshness_policies(compile_result)
Section titled “per_model_freshness_policies(compile_result)”Indexes freshness_policy_from_model by model name across a whole compile
result. A model without [freshness] is absent from the dict. Callers can
therefore use .get(model_name) and fall back to the pipeline-level default.
from dagster_rocky import RockyResource, per_model_freshness_policies
rocky = RockyResource(config_path="rocky.toml", models_dir="models")compile_result = rocky.compile()policies = per_model_freshness_policies(compile_result)# {"fct_daily_orders": <FreshnessPolicy>, ...}API choice: FreshnessPolicy.time_window
Section titled “API choice: FreshnessPolicy.time_window”dagster-rocky uses the Dagster 1.12+ constructor
FreshnessPolicy.time_window(fail_window=...).
It does not use the legacy FreshnessPolicy(maximum_lag_minutes=...), which
is deprecated.
This means:
- Compare in tests with
policy.fail_window.to_timedelta().total_seconds(). Dagster wraps thetimedeltain aSerializableTimeDelta, which does not compare equal to a plaintimedelta. - The check shows up under “Freshness” in the asset detail page, with the
fail_windowvalue.