Back to Blog

Finding Out Why Your Power BI Report Is Slow with Performance Analyzer

July 8, 20267 min readMichael Ridland

Slow Power BI reports cost more than people admit. When the executive dashboard takes forty seconds to render, executives stop opening it. When the sales team's report churns every time someone clicks a slicer, they export to Excel and never come back. I've watched genuinely good analytics work die in production not because the numbers were wrong but because nobody could bear to wait for them. In a few of our engagements the brief was "our team won't use Power BI" and the root cause was simply that the flagship report was painful to open.

The frustrating part is that most teams respond to a slow report by guessing. Someone blames the gateway. Someone else blames the data volume. A contractor suggests upgrading the capacity, which costs real money and often fixes nothing, because the actual problem was one bad DAX measure sitting behind one matrix visual.

Power BI Desktop ships with the tool that replaces the guessing, and it's had years to mature: Performance Analyzer. Microsoft's documentation covers it at examine report element performance, and it's worth a read, but the docs tell you what the buttons do. This post is about how to actually use it, because we run this exact process on client reports and the workflow matters more than the feature list.

What it does

Performance Analyzer lives in the Optimize ribbon in Power BI Desktop. You start recording, interact with the report - refresh the visuals, click a slicer, change a page - and it logs what every visual did and how long each step took, in milliseconds. Stop recording and you have a per-visual breakdown you can sort, expand, and export.

For each visual, the time splits into three buckets, and understanding these three buckets is genuinely the whole skill:

DAX query is the time spent asking the model for data and waiting for the answer. Every visual generates a DAX query behind the scenes; this number tells you how long the engine took to answer it.

Visual display is rendering time - how long the visual took to draw itself once the data arrived. Maps fetching background tiles, tables laying out thousands of rows, custom visuals doing whatever custom visuals do.

Other is the one everyone misreads. It's mostly time the visual spent waiting in the queue behind other visuals, because visuals don't all execute simultaneously. A visual showing 8,000ms in Other is usually not slow itself; it's stuck behind everything else on the page. High Other numbers across the board are the signature of a page with too many visuals, and the fix is subtraction, not tuning.

That last point deserves repeating because it changes diagnoses completely. I've reviewed reports where a previous developer spent days optimising a measure on a visual whose real problem was queue time. The measure was fine. The page had forty-one visuals on it. No DAX optimisation on earth rescues that page.

The workflow we actually use

When a client hands us a slow report, the first hour looks like this.

Clear the caches first. Power BI caches visual results, so the second refresh of a page is always flattering. To measure honestly, use a fresh session or force genuinely new queries; otherwise you're profiling the cache, not the report. When we do formal before-and-after comparisons for clients we're careful about this, because it's embarrassingly easy to "prove" a fix worked when all you proved is that caching works.

Record a full page refresh, then sort by duration. In nearly every slow report, a handful of visuals account for most of the pain. Power is in the sorting: you're not looking for a complete picture yet, you're looking for the worst three offenders.

Read the buckets before touching anything. Big DAX query number? The problem is the measure or the model. Big display number? The visual itself - often a table with too many rows, a high-cardinality scatter chart, or a third-party custom visual that seemed like a good idea at the time. Big Other? Count the visuals on the page and have an honest conversation about whether they all need to exist.

For the DAX-heavy visuals, use Copy query. This is the underrated feature of the whole tool. Performance Analyzer hands you the exact DAX query the visual ran, which you can paste into DAX query view or DAX Studio and work on directly - server timings, storage engine versus formula engine, the proper drill-down. Performance Analyzer finds the crime scene; DAX Studio does the forensics. They're a pair, and anyone doing serious model work should be comfortable in both.

Then fix, re-record, and compare. One change at a time. It's slower than heroically rewriting six measures in an afternoon, but you learn which change mattered, and that knowledge compounds across the rest of the report.

What the numbers usually tell us

After enough of these audits you see the same handful of diagnoses on repeat, so here's the honest pattern-matching.

Slow DAX query times usually trace back to the model, not the measure syntax. Iterators grinding over million-row tables, FILTER wrapped around entire tables where a simple filter argument would do, and above all bi-directional relationships and poorly shaped models that force the engine to do far more work than the visual needs. Sometimes the fix is rewriting a measure. Just as often it's a star schema conversation the organisation has been avoiding for two years. Performance Analyzer won't say "your model shape is wrong" in so many words, but when every visual on every page shows heavy query times, that's the message.

Slow display times are usually self-inflicted at the visual level. Tables trying to render ten thousand rows nobody will scroll through. Custom visuals from the marketplace that were never built for the data volume. Slicers with tens of thousands of distinct values. The fixes are unglamorous: fewer rows, fewer data points, standard visuals where they'll do.

And the queue-time page - many visuals, everything waiting on everything - is an information design problem wearing a performance costume. The best-performing reports we build tend to have restrained pages that answer one question well, with drill-through for detail. Users like them more anyway. Performance and usability point the same direction surprisingly often.

Where it stops helping

Fair warning about the tool's limits, because it has real ones.

Performance Analyzer runs in Desktop, on your machine, against whatever your Desktop file connects to. It won't capture what your users experience in the service - capacity load, gateway latency on DirectQuery sources, that Monday 9am spike when the whole company opens the same dashboard. A report can profile beautifully in Desktop and crawl in production. For the service-side story you need capacity metrics and query logging; different tools, different post. Treat Desktop numbers as the floor of user experience, not the estimate.

It also tells you what is slow, never why in any deep sense. The why lives in DAX Studio, in the model design, and frankly in experience. And on DirectQuery reports, remember the DAX time includes the source database's time, so the fix may belong to whoever owns the SQL side rather than to the report author.

None of that is a criticism, really. It's a free, built-in profiler that turns "the report feels slow" into "this visual spends 6,200ms in this query," and that sentence is where every real fix starts.

Make it a habit, not a rescue

The teams that get the most out of Performance Analyzer run it before publishing, not after the complaints. A five-minute recording on each page before a report ships catches the worst offenders while they're cheap to fix. Bake it into your definition of done. We include a performance pass in our Power BI consulting delivery standard for exactly this reason - retrofitting performance into a report the business already resents is far harder work than getting it right the first time.

It matters more, not less, as reporting stacks get more ambitious. If you're layering AI on top of your BI - natural language Q&A, agents summarising dashboards, the kind of work we do under AI for business intelligence - all of it issues queries against the same model your visuals use. A model that makes visuals crawl will make an agent crawl too, except the user can't see a spinner and just assumes the AI is bad. Clean, fast semantic models are the foundation either way.

So before you blame the gateway, upgrade the capacity, or rebuild the report from scratch: open the Optimize ribbon, hit record, refresh the page, and sort by duration. Ten minutes of measurement beats a week of guessing, every single time.