Skip to main content
Caching is available on Lightdash Cloud and on self-hosted instances with a valid Enterprise license. Filter value caching is available on all Cloud plans; results caching requires Enterprise. Lightdash supports two types of caching:
  1. Cached Filter values - enabled for every cloud user without requiring any configuration.
  2. Cached results for Charts and Dashboards - available on Enterprise; project admins enable and configure it themselves.

Filter value caching

This type of caching works without any configuration for cloud users. You’ll see a message in your filter values that tells you when the cached filter values were loaded from (usually within the last day). To refresh the values, click Results loaded at: Lightdash clears the list and queries your warehouse again, skipping the cache. If a value still looks out of date after a refresh, the warehouse table hasn’t changed yet.
Filter value dropdown listing company names, with "Results loaded at 1/20/2025, 10:56 AM" under the last value
If you search filter values by starting to type, Lightdash will also cache those values so the next time you need the same search the values will be shown much faster. The Results loaded at message doesn’t appear for dimensions with fetch_from_warehouse: false, or for dimensions with a static values list until you start typing. Static values come from your YAML, so update them there.

Chart and dashboard results caching

Results caching is off by default. Project admins turn it on and set its cache duration themselves under Project settings → Results caching — there’s no need to contact the Lightdash team. A cache timestamp in the dashboard header confirms it is active; if no timestamp appears, it is not enabled.The one exception is a self-hosted instance that still sets the deprecated RESULTS_CACHE_ENABLED environment variable: it forces caching on or off for every project, the toggle in project settings is locked, and the page tells the admin to contact their instance admin to change it.
Popular charts and dashboards will load faster when caching is enabled. The first user to visit a chart or dashboard each day will load fresh results from the warehouse, which get cached. After that, all following visits to the same chart or dashboard will load from the cached results. Any changes to the chart query or dashboard queries (user attributes, filters, limit, date zoom) will trigger new queries to the warehouse and create a separate cached results entry. Caching popular charts and dashboards will reduce warehouse costs to the organization by reducing the number of queries; it also improves server performance and makes the user experience much faster in Lightdash.

Scope of the cache

Each project turns caching on or off, and sets its own cache duration, under Project settings → Results caching — see Cache duration per project. There is no way to enable or disable caching for an individual dashboard. These Lightdash features use caching when it’s turned on for the project:
  • Saved Charts are cached based on the last refresh in any context (edit mode, view mode, dashboard refresh, etc.), but queries made while editing are NOT cached or pulled from cache.
  • Dashboard tiles (internal and embedded) will use the cache from saved charts they reference. If charts only exist on a single dashboard, they will refresh whenever you click the Refresh button on the dashboard. Embedded dashboards have no Refresh button, so embedded viewers see cached results until they expire. To control how fresh embedded data is, set the project’s cache duration; a shorter duration sends more queries to the warehouse.
  • SQL runner queries including saved SQL charts and dashboard SQL chart tiles are cached through the same execution path as metric-based charts. Note that the SQL runner does not have a UI button to force-refresh or invalidate the cache — results remain cached until the cache expires.
  • Metrics Catalog queries go through the same async query service and are cached like any other query.
  • Data apps run every metric query through the same async query service and are cached like any other query, including live-linked charts. The Refresh button in the app header (while building or viewing) invalidates the cache for that app and re-queries the warehouse fresh for the rest of the session, the same way the dashboard refresh button does. Because the cache key is project ID plus generated SQL, apps with lots of interactive filter controls produce more distinct cache entries than an equivalent dashboard — the first hit on each filter combination still goes to the warehouse.
These Lightdash features DO NOT use caching:
  • Scheduled Deliveries and Google Sheets syncs run a fresh warehouse query by default. To reuse unexpired cached results instead, turn on Use cached results when available on the delivery or sync. The option isn’t offered for data app deliveries.
  • Editing a saved chart — actions in edit mode (such as changing columns, filters, or other query parameters) explicitly bypass the cache to ensure you always see fresh results while building a query.
  • External connections in data apps — requests to third-party HTTP APIs are runtime fetches through the Lightdash proxy and are not covered by results caching.

Cache Mechanism

The cache is stored in S3 and the cache identifier is based on the project ID and the generated SQL. This means that any change to the selected columns, filters, joins, user attributes, etc. will trigger a new query to the warehouse and add a new cache entry for that query. User attribute values in a sql_filter are written into the generated SQL, so users with different attribute values never share a cache entry; users with the same values share one, because they see the same rows. Fields a user’s required_attributes don’t allow are checked before any SQL is built, so a query that selects one returns a Forbidden error instead of cached results.

User-level caching

When a project is configured to require user credentials, cached results are scoped to each individual user. This means:
  • Each user’s queries are cached separately based on their personal warehouse credentials
  • Users cannot access cached results from other users’ queries
  • This ensures data access controls are maintained at the individual user level

Filtering with time values and caching

When using filters with datetime values, the specificity of the time component affects caching behavior:
  • Dynamic datetime values with seconds (e.g., 12:11:25) will generally not benefit from caching because each query generates a unique timestamp, creating a new cache entry every time.
  • Definite times (e.g., 12:00:00) or dates without time components will cache effectively because they produce consistent SQL queries that can be reused.
Best practices for cacheable time filters:
  • Use date-only filters when possible (e.g., 2024-01-15 instead of 2024-01-15 12:11:25)
  • Round times to the nearest hour or fixed interval (e.g., 12:00:00 instead of 12:11:25)
  • Avoid filters that use dynamic “current time” functions with second precision
This ensures your queries can leverage cached results and reduce warehouse load.

Cache expiry and invalidation

Cached results automatically expire after 24 hours by default. The instance default is set by CACHE_STALE_TIME_SECONDS and applies to every project that hasn’t set its own duration. Cache expiry is rolling, not scheduled. It’s based on the age of each cached result, not a fixed time of day. For example, if a dashboard is first loaded at 2:00 PM, its cache expires at 2:00 PM the next day. This means different dashboards and charts may have different cache ages depending on when they were last refreshed.

Cache duration per project

Project admins turn caching on and set the cache duration for a single project under Project settings → Results caching. This page is available to any project whose organization has a valid Enterprise license. Turn off Use the default cache duration and enter a whole number of minutes between 1 and 43200 (30 days). Leaving the toggle on falls back to the instance default. On a self-hosted instance that still sets the deprecated RESULTS_CACHE_ENABLED environment variable (see environment variables), caching is forced on or off for every project and the toggle here is locked — contact your instance admin to change it instead.
If your dashboards report on “yesterday’s data” and you want users to always see fresh results in the morning, set a shorter cache duration (for example, 8 hours) so that results cached during the workday expire overnight.
The dashboard header displays the date and time of the chart with the oldest cache. If no time is displayed, then no charts are cached. You can invalidate and refresh cached dashboard results by pressing the dashboard refresh button. A cached result is served as stored until it expires, even one cached while the underlying table was empty or being rebuilt. If tiles show empty or null values for a filter value while Explore shows the right numbers, press the dashboard refresh button: reloading the browser page serves the same cached result. Running the same query in Explore also replaces the entry, because Explore skips the cache lookup and its fresh result becomes the newest entry for that SQL. If your tables are rebuilt on a schedule, set a cache duration that fits that schedule.
Dashboard header reading "Dashboard uses cached data from Jan 20, 2025 11:07 AM" beside a refresh button
There’s no button in the Lightdash UI to invalidate a single Saved Chart’s cache outside of a dashboard. You can do this through the API: set invalidateCache: true on a request to the execute saved chart or execute dashboard chart endpoint to bypass the cache and re-run that chart’s query, which repopulates its cache entry.

Clearing cached results for a project

Project admins can clear every cached result for a project from Project settings → Results caching:
  • Clear cache now invalidates every cached result in the project immediately. The next load of each chart, dashboard, or API query runs against the warehouse and repopulates the cache.
  • Scheduled clearing runs the same clear automatically — daily or weekly, at one or more hours, in the project’s default time zone.
To invalidate the cache from a script or a data pipeline, call one of these endpoints with a personal access token (Authorization: ApiKey <token>). All three require project admin access and results caching turned on for the project; query history and existing result files are kept, and the next run of the affected chart, dashboard, or project queries the warehouse and repopulates the cache: Call the project-level endpoint from a data pipeline once a run finishes, so the next person to open a chart or dashboard gets fresh results instead of what was cached before the run. See the API reference for full request and response details.

Results caching vs pre-aggregates

Lightdash has two independent systems for speeding up queries: results caching (documented above) and pre-aggregates. They work differently and are designed to be used together, not as replacements for each other. Both act only on query execution: they shorten or skip the warehouse part of loading a chart or dashboard. Neither changes the time your browser spends loading the dashboard and rendering its tiles, so a dashboard whose every query is served from the cache or a pre-aggregate still takes a moment to open — longer with many tiles or heavy custom visualizations.

Results caching

Results caching stores the exact result of any query that runs through Lightdash, keyed by a hash of the generated SQL, and serves subsequent identical queries from S3 until the entry expires (24 hours by default, configurable per project). It covers every query shape — including custom metrics, table calculations, and SQL runner queries — but the first run of each unique query still hits your warehouse, and any change to the query (a different filter, column, limit, or user attribute) produces a new entry and another warehouse query.

Pre-aggregates

Pre-aggregates are summary tables you define in your dbt YAML. Lightdash materializes them on a schedule (or on compile, or manually) and stores the results in S3. When a user query matches the pre-aggregate’s dimensions, metrics, filters, and granularity, Lightdash serves the query from the materialized data using in-memory DuckDB workers. The warehouse is not touched at query time, even on the first query. A single pre-aggregate can serve many different queries. A daily pre-aggregate with five dimensions can answer day, week, month, quarter, and year queries across any subset of those dimensions and with any narrower filter. Results caching, in contrast, needs one cache entry per unique SQL.

Key differences

When to use which

Use pre-aggregates when:
  • You have high-traffic dashboards with predictable query patterns
  • You want to reduce warehouse cost or improve latency on the first query, not just repeat visits
  • The metrics are re-aggregatable (sum, count, min, max, average)
  • You’re willing to design and schedule the materializations
Use results caching when:
  • Query patterns are ad-hoc or unpredictable
  • You need features that pre-aggregates don’t support, such as count_distinct outside an exact match, Parameters, or raw SQL table calculations
  • You’re using the SQL runner
  • You don’t want upfront configuration work
In most cases, both should be enabled. Pre-aggregates handle your heaviest, most predictable workloads. Results caching is the safety net for everything else.

Using both together

When both systems are enabled, they act as two layers of caching. A query that matches a pre-aggregate is served from the materialized data by DuckDB workers. The result of that DuckDB query can then be stored in the results cache, so subsequent identical requests skip even the DuckDB step and return the cached result directly. This means pre-aggregates eliminate the warehouse hit, and results caching eliminates repeated computation on top of that.