Tableau Course
Dashboard Performance
A beautiful dashboard that takes 30 seconds to load gets ignored. Performance is not an afterthought — it is part of design. This lesson covers how to find what is slowing a dashboard down, and the practical changes that make the biggest difference.
The Performance Recorder
The Performance Recorder is Tableau's built-in profiling tool. It records a timeline of every event that happens while a view loads — query execution, rendering, layout computation, and more — and shows you exactly where time is being spent.
Reading the Performance Timeline
The event types you will see most often and what they mean:
| Event | Meaning | Typical Fix |
|---|---|---|
| Executing Query | Time spent sending SQL to the data source and waiting for results | Switch to an extract, add a data source filter, reduce row count |
| Geocoding | Time looking up geographic coordinates for location fields | Pre-join lat/long columns into the data source so no lookup is needed |
| Rendering | Time drawing marks on the screen after data is returned | Reduce mark count — aggregate to a higher level or use context filters |
| Computing Layout | Time recalculating container and tile positions when the view resizes | Simplify nested containers, fix dashboard to a single size |
| Computing Totals | Separate queries fired just for grand totals and subtotals | Disable totals that are not needed, or compute them in the data source |
Extracts vs Live Connections
The single biggest performance lever in most dashboards is whether the data source is a live connection or a Tableau Extract (.hyper). Understanding the tradeoff tells you when to use each.
Every filter, parameter change, and page load fires a fresh SQL query to the original database. As fast as the database is — no faster. Large tables with no indexes will be slow every time.
Data is copied into a column-store file optimised for Tableau's query engine. Queries on a local or server-cached extract are typically 10–100× faster than the equivalent live query on a large table.
Reducing Extract Size
A smaller extract loads faster and uses less memory on the server. There are three ways to reduce extract size without losing the data the dashboard actually needs.
Optimising Queries
Even on an extract, poorly structured calculations and filters generate inefficient queries. These are the most common query-level causes of slow dashboards.
| Cause | The Problem | The Fix |
|---|---|---|
| Too many marks | A scatter plot with 500,000 individual points forces Tableau to draw every mark — slow render and noisy chart | Aggregate to a higher level, use density marks, or add a context filter to limit rows before rendering |
| Unanchored LOD expressions | A FIXED LOD with no filter fires a full-table scan on every load, even if the user only needs one region | Add a context filter before the LOD so Tableau limits the scan scope before evaluating the expression |
| String-heavy calculations | CONTAINS(), REGEXP_MATCH(), and nested IF/ELSEIF on string fields scan every row character by character | Compute the category or flag in the data source before connecting, and store it as an integer or boolean |
| Too many quick filters | Every visible quick filter fires its own query to populate the filter list — 8 visible quick filters can mean 8 + N queries on every load | Set filters to "Only Relevant Values" carefully and consolidate into a parameter where possible. Use "At Context Filter level" for heavy filters |
| Unnecessary joins | Joining tables in Tableau when only one table is used in most views forces the join on every query | Use Relationships instead of joins — Tableau only executes the join for sheets that actually need both tables |
Context Filters for Performance
A context filter runs before all other filters and limits the dataset that subsequent filters, LOD expressions, and table calculations operate on. Setting a high-cardinality filter — such as Region or Year — as a context filter can make every other query in the dashboard dramatically faster because all subsequent queries scan a fraction of the data.
In the Filters shelf, right-click any filter → Add to Context. The filter pill turns grey to indicate it is now a context filter. Only one context filter runs at a time per data source — if you add multiple, they all become context filters that chain together.
Dashboard-Level Performance Habits
These habits apply at the dashboard design level, not the calculation level. They are quick wins that compound — doing all of them on a slow dashboard often cuts load time in half before touching a single calculation.
Every sheet on a dashboard fires its own set of queries on load. A dashboard with 12 sheets fires 12+ queries simultaneously. Aim for 4–6 sheets per dashboard and use show/hide containers to defer hidden sheets until clicked.
A filter set on the initial load — such as "Year = Current Year" — limits every query that fires when the dashboard first opens. Without an initialisation filter, all queries run against the full dataset on every first load.
A filter action that passes a selection from a 50,000-row source sheet to a target sheet fires a new query on every click. If the source sheet has many marks, switch to a highlight action or pre-filter the source to a smaller set.
Tableau sometimes combines multiple queries into one — called query fusion — when sheets share the same fields and filters. Keeping related sheets on the same data source with the same context filters maximises the chance Tableau can fuse queries and reduce round trips to the database.
A Performance Debugging Workflow
Performance work follows the same logic as any debugging task: measure first, change second. The most common mistake is guessing at the cause and making changes without recording a baseline. Use the Performance Recorder every time — it is the only reliable tool for this. The second most common mistake is optimising the wrong event. A query that runs in 0.3 seconds followed by a render that takes 6 seconds is a rendering problem, not a query problem. Read the timeline first before touching anything.
Practice Questions
1. A dashboard is loading slowly. What are the steps to use the Performance Recorder to find which event is taking the most time?
2. An extract contains 5 years of sales data but the dashboard only ever shows the last 3 years. How do you reduce the extract to only store the relevant rows?
3. A FIXED LOD expression is running slowly against a 10 million row dataset. The dashboard always has a Region filter applied. How do you use a context filter to speed up the LOD?
Quiz
1. The Performance Recorder shows that the Executing Query event is taking 8 seconds on a dashboard connected to a live SQL database. The data only needs to be refreshed once per day. Which change is most likely to fix the bottleneck?
2. A wide source table has 80 columns but the dashboard only uses 12 of them. How do you prevent the unused columns from being stored in the extract file?
3. A scatter plot with 500,000 individual transaction marks loads slowly. The Performance Recorder shows the Executing Query event finishes in 0.4 seconds but the Rendering event takes 9 seconds. Which event is the bottleneck and how do you fix it?
Next up — Lesson 48: Dashboard Best Practices — design principles, layout standards, and the habits that separate good dashboards from great ones.