Excelgoodies logo +1 650 491 3131

LEARN THIS HANDS ON

Power BI Reporting

ET . Live Online FILLING FAST
View all upcoming batches
Measuring and Communicating Power BI Report Performance: From Analyzer Traces to UX Tweaks That Actually Help

Measuring and Communicating Power BI Report Performance: From Analyzer Traces to UX Tweaks That Actually Help

Your monthly executive report is finally getting attention, but now the complaint is different: “It takes forever to load, and nobody knows what’s happening.” The dataset sits in a Fabric capacity, visuals spin, and you’re stuck between vague user feedback and equally vague performance advice.

This article walks through a concrete way to measure and communicate Power BI report performance using Performance Analyzer, Fabric metrics, and a handful of UX tweaks that actually reduce wait time and frustration.


Scenario: The Slow Executive Overview in a Fabric Capacity

Picture a common setup:

  • A semantic model in a Fabric Power BI capacity (F64 or similar).
  • Mixed storage modes: one large Import table, a DirectQuery table to a SQL warehouse, and a couple of small dimensions.
  • A report with:
    • A main summary page with 12 visuals.
    • A few bookmarks for different executive views.
    • Several complex DAX measures using CALCULATE, FILTER, and SUMX over large tables.

Symptoms:

  • First page load takes 8–15 seconds for most users.
  • Slicers feel laggy; changing the main date range causes all visuals to spin.
  • Capacity admins see intermittent spikes in Fabric capacity CPU and memory.
  • Users complain, but nobody can show where the time is going.

We’ll use this scenario to:

  1. Measure report-level performance with Performance Analyzer.
  2. Link those traces to Fabric capacity metrics.
  3. Apply targeted DAX, model, and UX tweaks.
  4. Communicate the before/after in a way stakeholders understand.

Step 1: Use Performance Analyzer to Get Hard Numbers

Performance conversations go nowhere until you have timings per visual.

Enabling Performance Analyzer in Power BI Desktop

In Power BI Desktop:

  1. Go to View > Performance Analyzer.
  2. Click Start recording.
  3. Click Refresh visuals (or interact with slicers/bookmarks as users do).
  4. After the interaction completes, expand each visual in the pane.

For each visual, you get three key timings:

  • DAX query – time spent executing the query against the semantic model.
  • Visual display – time to render the visual (layout, drawing, etc.).
  • Other – time for non-query operations (model operations, background tasks).

Export the results:

  1. Click Export in Performance Analyzer.
  2. Save as a JSON file.

This gives you trace data you can analyze or share.

What to Look for in the Executive Overview Report

For our scenario, focus on:

  • Top 3 slowest visuals by DAX query time on first page load.
  • Visuals where visual display is high (e.g., custom visuals or heavy conditional formatting).
  • Slicer interactions that trigger multiple queries (check the timings after a slicer change).

Patterns that matter:

  • One or two visuals consistently taking >3–4 seconds of DAX time.
  • A page where total DAX time (sum of visuals) is high and Fabric metrics show capacity pressure.

Those visuals are your first optimization targets.


Step 2: Map Desktop Timings to Fabric Capacity Metrics

Performance Analyzer tells you what the report is doing. Fabric metrics tell you what the capacity is doing.

In the Power BI service (Fabric capacity):

  1. Go to Capacity settings for your Fabric capacity.
  2. Open Metrics (the Fabric capacity metrics app or the built-in metrics view, depending on your configuration).
  3. Filter to the time window when you captured Performance Analyzer traces.

Key metrics to correlate:

  • CPU utilization – sustained high CPU during report interactions can indicate heavy DAX, complex relationships, or many concurrent queries.
  • Memory usage – spikes during initial page load or refreshes indicate large Import models or many concurrent users.
  • Query wait time / throttling indicators – show when queries are queued due to capacity limits.

If you see:

  • Performance Analyzer: one visual with 6–8 seconds DAX time.
  • Fabric metrics: CPU spike and possible throttling at the same time.

Then you’re dealing with a combination of:

  • Heavy query logic (DAX, DirectQuery complexity).
  • Capacity contention (other workloads on the same capacity).

This matters for communication: sometimes the fix is in the report, sometimes in capacity configuration, and often in both.


Step 3: Fix the DAX and Model Issues You Can See

Once you know which visuals are slow, you need to check whether they’re slow because of:

  • DAX patterns that force more work than necessary.
  • Storage mode choices (DirectQuery vs Import vs Dual).
  • Relationship and filter direction complexity.

Example: Simplifying a Common Heavy Measure

Say the slow visual is using a measure like:

Revenue Selected Period :=
VAR SelectedStartDate = MIN('Date'[Date])
VAR SelectedEndDate   = MAX('Date'[Date])
RETURN
CALCULATE(
    SUM('Sales'[Revenue]),
    FILTER(
        ALL('Date'),
        'Date'[Date] >= SelectedStartDate &&
        'Date'[Date] <= SelectedEndDate
    )
)

Issues:

  • FILTER(ALL('Date')...) can scan the entire Date table, even though the filter context already contains the selected range.
  • This often isn’t necessary if your visuals are already filtered by the Date slicer.

A simpler pattern that relies on the existing filter context:

Revenue Selected Period :=
SUM('Sales'[Revenue])

If you need a specific range relative to a slicer (e.g., last 90 days), use DATESINPERIOD or DATEADD on a properly marked Date table:

Revenue Last 90 Days :=
CALCULATE(
    SUM('Sales'[Revenue]),
    DATESINPERIOD(
        'Date'[Date],
        MAX('Date'[Date]),
        -90,
        DAY
    )
)

This avoids scanning the entire Date dimension with a custom filter.

DirectQuery vs Import for the Executive Overview

If your slow visual is hitting a DirectQuery table:

  • Every interaction can generate one or more queries to the underlying source.
  • Query performance is bounded by the source and network, not just the Power BI engine.

For a high-traffic executive page:

  • Consider Import for the core aggregated tables used on that page, if latency is more important than real-time.
  • Use DirectQuery only for genuinely real-time elements, and isolate them to fewer visuals.

Be explicit with stakeholders: moving a table from DirectQuery to Import changes the data latency profile, but can significantly reduce query time.

Relationship and Filter Direction Checks

Use Model view in Power BI Desktop to review:

  • Relationship cardinality (avoid unnecessary many-to-many relationships).
  • Bi-directional filters used only where they’re needed.

Complex filter paths can increase query planning and execution time. If your slow visual depends on a chain of relationships, see if you can:

  • Introduce a simpler bridge table.
  • Reduce bi-directional relationships to single direction and use TREATAS in measures where cross-filtering is needed.

Step 4: UX Tweaks That Actually Reduce Wait Time

Not all performance fixes are engine-level. Some are about not asking the engine to do so much work per interaction.

1. Limit Initial Page Load Work

For the executive overview page:

  • Reduce the number of visuals that load immediately. Use bookmarks or buttons to show secondary views on demand.
  • Avoid loading detailed tables or matrices on the first page; link to a detail page instead.

You can measure the impact by:

  • Recording Performance Analyzer before and after removing a few visuals.
  • Comparing total DAX time across visuals on first load.

2. Use Slicer Design to Avoid Expensive Requeries

Some slicer patterns cause many visuals to re-evaluate more often than needed.

Practical tweaks:

  • Use a single primary Date slicer instead of multiple overlapping date filters.
  • Prefer dropdown or relative date slicers over multi-select lists when users rarely need multi-select.
  • Avoid slicers on high-cardinality fields (e.g., transaction IDs) on summary pages.

3. Avoid Overly Complex Conditional Formatting

Heavy conditional formatting can increase visual display time.

If Performance Analyzer shows high visual display time for a table or matrix:

  • Reduce the number of rules and measure-based formatting expressions.
  • Move some formatting logic into the data model (e.g., precomputed status columns) instead of complex per-cell measures.

4. Use Loading States to Communicate What’s Happening

You can’t always make everything fast, but you can make the waiting clearer.

Practical options:

  • Use text boxes or cards that show a simple message when a page is filtered to a heavy scenario (e.g., “Detailed view – queries may take a few seconds”).
  • Use separate pages for heavy detail views and label them clearly, so users know they’re moving from “summary” to “analysis” mode.

This doesn’t change DAX time, but it reduces user frustration and support noise.


Step 5: Communicate Performance in a Way Stakeholders Understand

Once you have traces and metrics, you need a simple narrative.

Build a Before/After View from the Executive Report

From Performance Analyzer exports and Fabric metrics:

  1. Pick 3–5 key interactions:
    • First load of the executive overview page.
    • Changing the main Date slicer.
    • Opening the detailed table page.
  2. For each interaction, record:
    • Total DAX time (sum of visuals involved).
    • Total visual display time.
    • Any Fabric capacity observations (CPU spike, throttling).

Present this in a small table or slide:

  • Before: total time and main causes (e.g., “Complex DAX measure on revenue visual, DirectQuery source”).
  • Change: what you changed (e.g., simplified DAX, moved table to Import, reduced visuals on first page).
  • After: new timings.

Avoid promising exact numbers unless you can reproduce them; focus on relative improvements and clearer behaviour.

Separate Report-Level vs Capacity-Level Issues

Stakeholders often conflate report design with capacity sizing.

Be explicit:

  • Report-level fixes: DAX simplification, model changes, UX tweaks.
  • Capacity-level options: changing capacity SKU, isolating heavy workloads to a separate capacity, adjusting refresh schedules.

Use Fabric metrics to show when the report is slow because capacity is saturated vs when it’s slow even when capacity is healthy.


A Practical Takeaway: Make Performance a Measured Conversation

The concrete move is this: pick one slow page, run Performance Analyzer traces for realistic interactions, line them up with Fabric metrics, and then change only one or two things at a time. Each change should have a measurable impact on at least one of:

  • DAX query duration for specific visuals.
  • Total page load time.
  • Capacity pressure during key usage windows.

Once you can show those changes clearly, performance stops being a vague complaint and becomes a manageable part of your Power BI design process.

Editor's Note

This article reflects the shift from anecdotal complaints about slow Power BI reports to disciplined measurement and targeted fixes using Performance Analyzer, Fabric capacity metrics, and pragmatic UX changes in shared enterprise environments.

Professionals who want to apply these patterns to their own data can explore Excelgoodies' Power BI Training programme - taught live by instructors, with certification awarded once a real project is running at work.

Insights compiled through ongoing industry research and discussions within the Excelgoodies Analytics Community.

Power BI

New

Next Batches Now Live

Power BIPower BI
SQLSQL
Power AppsPower Apps
Power AutomatePower Automate
Microsoft FabricMicrosoft Fabrics
AzureAzure Data Engineering
Explore Dates & Reserve Your Spot → Reserve Your Spot →