Lakshya

Analytics & BI Tools · Chapter 11 of 18

Tableau internals: the engine, and the order of operations

Extracts, the calculation hierarchy, and the one diagram that explains why a filter sometimes has no effect.

7 min read1 diagramAll 18 chapters

Tableau's strength is genuinely different from Power BI's: it is built around visual analysis — exploring data by direct manipulation — rather than around building a model and reporting from it. That difference shows up in the engine, in the calculation model, and in what goes wrong.

Extract versus live, and what an extract actually is

A live connection issues a query to the source for every interaction. An extract is a compressed columnar snapshot in Tableau's own analytical engine — the same family of technique as the previous chapter: columnar layout, dictionary encoding, and query execution against compressed data.

The decision criteria are the ones from chapter 9, with one Tableau-specific addition: extract filters are applied when the extract is built. Data excluded there is not in the extract at all, so no dashboard filter can ever bring it back — and a user asking “why can't I see last year?” is frequently hitting an extract filter someone set two years ago and forgot.

The order of operations, which explains most confusing behaviour

ORDER OF OPERATIONS — WHY A FILTER SOMETIMES DOESN'T CHANGE THE NUMBER 1 · extract filters applied when the extract is built — the data is not even there 2 · data source filters applied at the connection, before anything else 3 · context filters create a temporary subset — THIS is what FIXED sees 4 · FIXED expressions ignore dimensions in the view; see only steps 1-3 5 · dimension filters the ordinary filter shelf 6 · INCLUDE / EXCLUDE evaluated WITH the view's dimensions 7 · measure filters after aggregation 8 · table calculations last — operate on the result table, not the data THE QUESTION THAT PICKS THE RIGHT TOOL Does this calculation need to be independent of what is on the canvas? → yes: a fixed-level expression → no, it should follow the view: include → it operates on displayed results: table calc The classic bug: a fixed-level expression that ignores the user's filter, because that filter is at step 5 and the expressionevaluated at step 4. Promote the filter to context and it works.
The evaluation order, with each filter type and calculation family placed on it. The bug at the bottom is the most common one in the product, and once you can read this diagram you can diagnose it in seconds.

Almost every “my filter isn't working” and “this number doesn't match” question is answered by this ordering. The key relationships:

  • Extract and data-source filters happen first, before the workbook sees anything.
  • Context filters create a temporary subset, and this is what a fixed-level expression sees. Promoting an ordinary filter to a context filter is the standard fix for ‘my fixed calculation ignores the user's selection’.
  • Fixed-level expressions evaluate before ordinary dimension filters — which is exactly why they ignore them. That is the designed behaviour and it is the single most reported bug that is not a bug.
  • Include and exclude expressions evaluate with the view's dimensions, after dimension filters, so they follow the canvas.
  • Table calculations are last, and this is the deepest conceptual point: they operate on the result table that the query produced, not on the underlying data. A running total, a percent of total, a rank — these are computed over what is already on screen. Which is why adding a filter changes a table calculation's result even though the filter was applied several steps earlier.

The question that picks the right calculation type

Does this calculation need to be independent of what is on the canvas?

Yes, it has a fixed grain regardless of the view — customer lifetime value, first purchase date, total orders per customer — then a fixed-level expression. This is the one that solves the classic cohort and per-entity problems that are otherwise very awkward.

No, it should respond to the dimensions in the view but add or remove one — then include or exclude.

It operates on numbers already displayed — running total, difference from previous, percent of total, rank — then a table calculation, and be explicit about its addressing and partitioning, because the default is a guess based on the current layout and it breaks the moment someone rearranges the view.

Being able to state that decision rule cleanly is more useful in an interview than knowing any particular function, because it is the thing people get wrong repeatedly.

Performance, in the order that actually pays

The built-in performance recorder gives you a timeline of query execution, layout and rendering, and reading it correctly means separating three quite different problems:

Symptom in the recorderWhat it meansWhat to do
Long executing queryThe source or the engine is slowExtract it, aggregate it upstream, or fix the source query
Long computing totals or calculationsTable calculations or complex expressions on many marksMove the work upstream, or reduce the marks
Long rendering with fast queriesToo many marks on screenThis is the one people miss — see below
Many separate queriesMultiple data sources, or blendingConsolidate, or join upstream

The mark count is the number nobody looks at. A scatter plot with 400,000 points is 400,000 objects to lay out and draw. The queries can be instant and the dashboard still unusable, and no amount of database tuning helps.

It is also almost always a design problem rather than a performance one: nobody can read 400,000 points. Aggregating, binning, or sampling makes the chart both faster and more legible, which is a rare alignment.

The related trap is dashboard density. Every additional worksheet on a dashboard is at least one more query. A dashboard with fourteen sheets and six filters is issuing a lot of work per page view, and the honest fix is usually to split it into two focused dashboards rather than to optimise the queries.

And data blending is slower than joining. Blending queries each source separately and combines the aggregated results in memory. It exists for cases where you genuinely cannot join upstream — different systems, different grains — and it is frequently used where a join would have been both faster and clearer.

Where Tableau genuinely wins, and where it costs

Wins: exploratory visual analysis is still its strongest suit, and the difference is real rather than aesthetic — the interaction model is built for someone thinking with the data rather than reading a prepared report. The default visual choices are better than most competitors'. And the analyst community and shared-visualisation culture around it is genuinely a resource.

Costs: the licensing model separates people who build from people who read, and organisations consistently underestimate how many of their users need the more expensive tier — the moment a ‘viewer’ needs to create their own view, they need a different licence. And there is no built-in semantic layer of the kind the next chapter describes, so metric consistency depends on discipline and on published data sources being actually used rather than copied.

Check yourself

Why does a fixed-level expression ignore my filter?Because fixed-level expressions evaluate before ordinary dimension filters. Promote the filter to a context filter and it will be visible to the expression.
What is fundamentally different about a table calculation?It operates on the result table already returned — the numbers on screen — not on the underlying data. That is why rearranging a view changes its result.
Queries are fast and the dashboard is still slow. What now?Mark count. Hundreds of thousands of marks cost layout and rendering time regardless of query speed — and a chart nobody can read is a design problem, not a performance one.
Why prefer a join over blending?Blending queries each source separately and combines aggregated results in memory. It exists for cases you genuinely cannot join, and it is routinely used where a join would be faster and clearer.
← Power BI internals: the model, and what DAX is really doingThe semantic layer, and who owns the metric →