A materialized windowed aggregation reads precomputed tiles that a backfill writes. Chalk stores each series of tiles under a materialization key: a hash of everything that determines the tiles’ contents, which is the aggregation, the aggregated column, the group-by keys, the bucket duration and start, the filters and the aggregation options. When a change to your project changes any of these, the deployment that ships it reads tiles under a new key, and those tiles hold nothing until you backfill them.

A materialized aggregate diff compares the materialization keys of your project’s feature graph with those of your environment’s active deployment, and lists each materialized aggregate feature whose keys differ. Run it before you deploy with chalk apply --plan --remote, or have Chalk run it as part of every chalk apply.


​
Requirements

Both ways of running the diff need these versions:

ComponentMinimum versionNeeded for
Chalk platformv3.43.94Running the diff in the build, and serving its result
Chalk CLIv1.58.0chalk apply --plan --remote

The diff runs on Chalk’s latest engine base image, not on the platform version your environment pins, so an environment pinned to an older platform version can still use it once its metadata plane runs v3.43.94 or later.

The diff is enabled per environment. Ask Chalk to enable it for your environment (Chalk staff: the mat_agg_diff_after_build feature flag).


​
Preview a change before you deploy

Run chalk apply with --plan --remote from your project’s root:

chalk apply --plan --remote

The command first does everything chalk apply --plan does: it validates your project locally, validates it against your environment, and prints the changes to features and resolvers. It then uploads your source as a plan deployment. Chalk builds that deployment’s Python environment, imports your code to extract its feature graph, and diffs the graph’s materialization keys against those of your environment’s active deployment. The CLI waits for the build and prints the report:

  ↗ Plan URL: https://chalk.ai/projects/.../environments/.../deployments/cmw82mquq002j01iulz03zqxd
Materialized aggregates compared against active deployment cmw63fr8q000101haml2571uz:
materialized aggregate features: 0 added, 0 removed, 1 changed, 174 unchanged
~ token.count__cnp_auths (windowed)
    + 7c71ee4044dc count(dec_plat_card_auth_event.id) by [dec_plat_card_auth_event.token_id] every 1d on dec_plat_card_auth_event.event_timestamp

A plan deployment builds no container image and is never activated. It appears in your environment’s list of deployments and finishes with the status EXPIRED, so it cannot be promoted later. Nothing in your environment changes.

--remote only applies together with --plan. It cannot be combined with --branch, because branch deployments are not compared with the active deployment, or with --from-image, because the diff needs the graph extracted from your source.

With --json, the command’s output gains a plan.materialized_aggregate_diff object:

FieldDescription
base_deployment_idThe deployment compared against: the environment’s active deployment when the plan build started. Absent when the environment had no active deployment, in which case every feature is added.
added_featuresFeatures only your project materializes.
removed_featuresFeatures only the active deployment materializes.
changed_featuresFeatures both materialize whose materialization keys differ.
unchanged_featuresFeatures both materialize with the same keys.
textThe report as the command prints it.
jsonThe full report, including every key of every added, removed and changed feature, as a JSON string.

Each list holds feature names, sorted.


​
Read the report

The report’s first line counts the features in each category. Each added, removed or changed feature follows on its own line:

MarkerCategoryWhat to do
+Added: only your project materializes the feature.Backfill it before you rely on its values.
-Removed: only the active deployment materializes the feature.Its backfilled tiles are no longer read once you deploy.
~Changed: both materialize it, but the set of keys it reads differs.Backfill the keys marked +.

The feature’s kind follows its name: windowed, group_by or scalar.

Below each feature, one line describes each materialization key that differs. Under a changed feature, + marks a key only your project reads, which has to be backfilled, and - marks a key only the active deployment reads. A key both versions read is not listed, since its backfilled tiles carry over. Each key line reads:

<hash> <aggregation>(<column>) by [<group keys>] every <bucket duration> on <time column>

followed by from <bucket start>ms when the buckets do not start at the Unix epoch, options [...] for aggregation options such as the k of an approximate top-k, and filters ... for the aggregation’s filters. <hash> is the first 12 characters of the materialization key’s hash.

A few properties of the comparison determine what counts as a change:

  • A windowed feature’s keys are the union of the keys of all its windows. Adding a window whose bucket duration matches an existing window’s leaves the keys, and the feature, unchanged.
  • Changes that do not affect the tiles, such as a feature’s description, owner, tags or max_staleness, do not change its keys.
  • An aggregation over a projection expression rather than a column has no tiles. It shows as (untiled: aggregates a projection expression).
  • The comparison is against the active deployment. If your local source is behind it, features added in the active deployment since then show as removed.

​
Diff every deployment

Once the diff is enabled for an environment, every chalk apply build runs it after it generates the proto graph, comparing the new deployment with the deployment that was active when the build started. It shows as the Diffing materialized aggregates step in the deployment’s build progress, and the report is printed in that step’s build logs.

This step does not block the deployment: if it fails, the deployment continues.

The report of any deployment whose build ran the step, including a plan deployment, is available from the BuilderService.GetMaterializedAggregateDiff RPC, which takes a deployment_id and returns the fields listed above. It returns no diff until the step has finished, or when the build ran no diff.


​
Troubleshooting

MessageCause
This Chalk API server does not support `chalk apply --plan --remote`.The metadata plane runs a platform version older than v3.43.94. The CLI checks this before it creates a plan deployment, so nothing is created.
plan-only builds are not enabled for this environmentThe diff is not enabled for the environment.
The plan build failed at "<step>", so it has no materialized aggregate diff.The plan build failed before or during the diff. Open the plan URL the command printed and read the failed step’s build logs. A failure while constructing the Python environment or generating the proto graph would fail a regular deployment of the same source too.
this engine base image's libchalk has no diff_materialized_aggregates (in the step’s build logs)Chalk’s latest engine base image for your environment is older than v3.43.94.
the proto graph of base deployment <id> was not found (in the step’s build logs)The active deployment’s feature graph is missing from object storage, so there is nothing to compare against.

To backfill the features the report lists, see Materialized Aggregations and chalk aggregate backfill.