Why cache matters
Every dashboard load triggers Malloy queries against BigQuery. Without cache, the same aggregations run on every page view — which means cost and latency scale with traffic, not with how often your data actually changes.
For most analytical workloads, data changes once a day or less. Adding a cache with a reasonable TTL makes dashboards fast for users and predictable in cost for you.
How it works: the sidecar file
Cache is configured per model using a sidecar file placed alongside the .malloy file. The sidecar has the same name as the model, with a .cache.yml suffix:
content/
models/
ec_revenue.malloy
ec_revenue.cache.yml ← cache config for ec_revenue.malloy
ec_performance.malloy
ec_performance.cache.yml
If no sidecar exists, queries run live on every request.
Working example
# content/models/ec_revenue.cache.yml
model: models/ec_revenue.malloy
defaults:
cache:
mode: auto
ttl_seconds: 1800
Field by field:
model: path to the model this cache config applies to, relative to the workspace root.defaults.cache.mode: set toauto. This is the only supported mode in the current version. It caches query results keyed by query name and parameter combination.defaults.cache.ttl_seconds: how long cached results are valid. After this time, the next request triggers a fresh query and repopulates the cache.1800= 30 minutes.
Choosing a TTL
Match TTL to how often the underlying data actually changes:
- Daily batch pipelines:
ttl_seconds: 86400(24 hours) - Hourly refreshes:
ttl_seconds: 3600(1 hour) - Near real-time: skip cache or use
ttl_seconds: 300(5 minutes) - Reports and document dashboards:
ttl_seconds: 1800(30 minutes) is a safe default
Setting a very short TTL on heavy queries does not make them fresher — it just makes them expensive. Match TTL to the actual data freshness SLA, not to how often users open the dashboard.
Cache and dashboard filters
Cache keys include the query parameters passed by dashboard filters. A user filtering by "2024" gets a cached result for that specific parameter combination. A user filtering by "2023" triggers a separate cache entry the first time, then hits cache on subsequent loads.
This means dashboards with many distinct filter combinations will have a larger cache warm-up cost. For document dashboards with a fixed default date, the cache is typically warm within one load.