Materialization
Asemic charts don’t scan your raw events on every query. They read a precomputed entity table: one row per user per day, holding that user’s properties as of that day. Computing it once and querying it many times is what keeps dashboards fast and warehouse bills sane. It is also why a published model needs backfilling before charts show data.
The entity table
For each day in a materialized range, every user active within the “Active days” window has a row carrying their properties: spend to date, days since registration, battles played, and whatever else the model defines. Metrics are computed from these rows. The table lives in your warehouse, in the dataset you chose as “Data model schema”.
Active days
“Active days” (default 90) controls how long a user keeps a row in the daily table after their last activity. A user who lapses stays present, with their properties frozen at their last state, for that many days, then drops out until they return.
The tradeoff: a longer window means lapsed users remain visible to cohorts and lifecycle metrics for longer (useful for churn and resurrection analysis), at the cost of a larger daily table. The 90-day default suits most games; change it in event setup only with a reason.
Coverage
Materialization is per-day, and each day is either full, partial, or none. The ⋮ menu → “Materialization coverage…” dialog shows the heatmap and the backfill actions. Two consequences worth internalizing:
- Gaps are per-day, not global. A chart over a range with missing days shows exactly those days as gaps; the rest of the range is fine.
- Backfills are incremental. Extending your history later only computes the days you add; nothing already materialized is redone.
Today is excluded from backfills: it is still being written, and materializes on the next day’s run.