Why Dashboards Get Slow (and How to Fix It)

โฑ๏ธ 3 min read ๐Ÿ“Š Visualization

Dashboards get slow because they run expensive queries against raw, row-level data every time someone opens them, instead of reading from data that's already been aggregated. The fix is almost never a bigger warehouse โ€” it's pre-aggregating the numbers the dashboard actually needs and querying that instead.

Quick answer: Slow dashboards are usually re-scanning millions of raw rows per chart on every page load. Fix it with a pre-aggregated summary table (built by a scheduled job, not on-demand), an extract/cache layer instead of a live connection for anything refreshed less than hourly, and by cutting the number of independent queries a single dashboard fires. A well-built dashboard should load in under 3 seconds.

What actually makes a dashboard slow?

Three things dominate: querying raw, unaggregated tables instead of pre-summarized ones; firing a separate query per chart instead of one shared query; and joining large fact tables at query time instead of pre-joining them in a nightly job. Any one of these turns a sub-second dashboard into a 10-30 second one once the underlying tables reach millions of rows.

Should a dashboard use an extract or a live query?

Use an extract (a cached, pre-computed snapshot) unless the dashboard genuinely needs to reflect data less than an hour old, like an operations or fraud-monitoring view. Live queries recompute the full result set on every page load and every filter change, which is fine at small data volumes and unbearable at large ones.

Live queryExtract / cached
FreshnessReal-timeAs of last refresh (e.g. hourly, nightly)
Load timeDepends on source system loadFast and predictable
Source system impactEvery viewer hits the databaseOne scheduled job hits the database
Best forOps monitoring, fraud alertsExecutive, sales, marketing reporting

What is pre-aggregation and why does it help so much?

Pre-aggregation means computing the sums, counts, and averages the dashboard needs ahead of time โ€” in a scheduled job โ€” and storing the result in a small summary table, so the dashboard queries thousands of rows instead of millions. A "revenue by day by region" chart doesn't need to scan every order row at view time if a nightly job already rolled orders up to daily-by-region totals.

-- Instead of the dashboard running this on every page load:
SELECT region, DATE(order_date) AS day, SUM(amount) AS revenue
FROM orders
GROUP BY region, DATE(order_date);

-- Pre-aggregate it nightly into a summary table:
CREATE TABLE daily_revenue_by_region AS
SELECT region, DATE(order_date) AS day, SUM(amount) AS revenue
FROM orders
GROUP BY region, DATE(order_date);

-- Then the dashboard just does:
SELECT * FROM daily_revenue_by_region WHERE day >= CURRENT_DATE - 30;

The pre-aggregated query above touches a table with one row per region per day instead of one row per order, so it stays fast even as order volume grows into the tens of millions.

How many queries should one dashboard fire?

As few as possible โ€” ideally one shared query per data source that every chart on the page reads from, rather than one query per chart. A dashboard with 8 charts firing 8 independent queries against the same table multiplies load on the source system by 8 for no analytical benefit.

Common mistakes

Pro Tip: Time your dashboard's load with the tool's own query inspector before assuming the warehouse is the bottleneck โ€” very often it's a single unindexed join or one chart pulling raw detail it doesn't display. Fix that one chart and the whole dashboard often gets fast again.

โ† Back to Visualization Tips