power-bi-performance-troubleshooting
Verifiedby github · Updated Apr 16, 2026
Systematic Power BI performance troubleshooting prompt for identifying, diagnosing, and resolving performance issues in Power BI models, reports, and queries.
See It In Action
Okay, I've gone through all the evidence — capacity metrics, DAX server timings, Performance Analyzer captures, model snapshot, and the incident timeline. Here's what happened and how to fix it today.
Root Cause Diagnosis
The April 12 refresh introduced multiple compounding problems. Page load went from ~4s to ~28s, and it's not one thing — it's five things stacking on each other:
1. Model bloat (+62% rows, +62% compressed size)
SalesFact went from 58M → 94M rows, model from 1.3 GB → 2.1 GB. That alone would slow things down, but it's made worse by three new high-cardinality text columns (OrderLineGuid, AccountOwnerEmail, PromoCodeRaw) that compress terribly and bloat memory.
2. AccountDim flipped from Dual to DirectQuery This is a big one. Every query touching account attributes now hits the source system live instead of the in-memory engine. The Top Accounts query went from 1.36s → 8.84s, and SE query fan-out jumped from 5 → 13 queries. Cache hit rate on that query dropped from 69% → 21%.
3. Relationships changed to bidirectional many-to-many
SalesFact→Targets went from single-direction one-to-many to bidirectional many-to-many. SalesFact→ProductDim also went bidirectional. This expands filter context across the entire model — the Gross Margin % measure went from 1.42s → 6.94s purely from filter propagation.
4. Four new visuals added to Executive Overview (7→11) Custom map visual, smart narrative, decomposition tree, and a tooltip page trigger. Each fires its own DAX queries on load. The custom map alone takes 7.5s, the decomposition tree 14.5s.
5. DAX anti-patterns now exposed at 94M row scale These measures were "fine" at 58M rows but fall apart at current volume:
YoY Sales Growth: nested CALCULATE/PREVIOUSMONTH without variables (540ms → 4210ms FE time)Pipeline Coverage Ratio: raw FILTER() on the full fact tableRevenue Rank: RANKX iterating over high-cardinality text columnDiscount Leakage: SUMX at transaction grain with expanded filter context (9.18s total)
The capacity metrics confirm the impact: during the exec usage spike yesterday, CPU hit 92%, memory 90%, 18 queries queued, 8 timeouts.
Same-Day Fix Plan (prioritized by impact)
Do these in order. Each one is independently deployable.
Fix 1 — Revert AccountDim to Dual/Import (est. impact: -30% query time)
In Power BI Desktop, change AccountDim storage mode back to Dual (or Import). This single change will bring Top Accounts, Revenue Rank, and Gross Margin queries back to in-memory speeds. Republish after.
Fix 2 — Revert relationships (est. impact: -20% query time)
SalesFact[AccountId] → Targets[AccountId]: change back to single-direction, one-to-many. If the many-to-many was intentional for a new visual, use CROSSFILTER() in just that measure instead.SalesFact[ProductId] → ProductDim[ProductId]: revert to single-direction.
This stops the filter context explosion that's hitting every visual on every page.
Fix 3 — Remove or hide the expensive new visuals (est. impact: -15% page load) Temporarily remove from Executive Overview:
- Geo Revenue Density (custom map) — 7.5s alone
- Discount Impact Decomposition tree — 14.5s
- Executive Commentary (smart narrative) — 5.3s
Move them to a separate detail page that execs can drill into on demand. This drops the query count on initial load from 11 visuals back toward 7.
Fix 4 — Refactor the top 4 slow DAX measures (est. impact: -15% query time)
YoY Sales Growth — wrap in VAR to avoid repeated context transitions:
YoY Sales Growth =
VAR _CurrentSales = [Total Sales]
VAR _PriorSales = CALCULATE([Total Sales], DATEADD(DateDim[Date], -1, YEAR))
RETURN
DIVIDE(_CurrentSales - _PriorSales, _PriorSales)
Pipeline Coverage Ratio — replace FILTER on fact table with KEEPFILTERS or move predicate to CALCULATE directly:
Pipeline Coverage Ratio =
CALCULATE(
[Pipeline Value],
SalesFact[Stage] = "Open" -- predicate, not FILTER(SalesFact, ...)
) / [Total Sales]
Revenue Rank — switch from text-based account context to integer key:
Revenue Rank =
RANKX(
ALL(AccountDim[AccountId]), -- integer key, not account name
[Total Sales]
)
Discount Leakage — reduce iterator grain or pre-aggregate:
Discount Leakage =
VAR _DiscountTotal =
SUMX(
SUMMARIZE(SalesFact, SalesFact[ProductId], SalesFact[AccountId]),
[Discount Amount]
)
RETURN
DIVIDE(_DiscountTotal, [Total Sales])
Fix 5 — Remove the three new high-cardinality text columns
OrderLineGuid, AccountOwnerEmail, PromoCodeRaw — if nothing on the report uses them, remove them from the model in Power Query. This will shrink the model back toward 1.3 GB and improve refresh time (34 min → closer to 19 min). If they're needed downstream, at minimum hide them and ensure no visual references them.
Fix 6 — Limit slicer cross-filter scope The Product Family slicer cross-filters all 11 visuals, and the Region slicer syncs across 3 pages. Disable sync on Region slicer (set to current page only). Reduce Product Family cross-filter to only the visuals that need it.
Execution Order for This Afternoon
| Step | Fix | Time to implement | Requires republish? |
|---|---|---|---|
| 1 | Revert AccountDim to Dual | 5 min | Yes |
| 2 | Revert relationships | 10 min | Yes (batch with #1) |
| 3 | Remove expensive visuals | 10 min | Yes (batch with #1-2) |
| 4 | Refactor DAX measures | 30-45 min | Yes (batch all) |
| 5 | Remove unused columns | 15 min | Yes (triggers refresh) |
| 6 | Limit slicer scope | 5 min | Yes (batch with above) |
Batch fixes 1-3 and publish first — that alone should get page load from ~28s back under 8-10s. Then do 4-6 in a second publish. You should be back near the original ~4s range after all six.
SKILL.md
Power BI Performance Troubleshooting Guide
You are a Power BI performance expert specializing in diagnosing and resolving performance issues across models, reports, and queries. Your role is to provide systematic troubleshooting guidance and actionable solutions.
Troubleshooting Methodology
Step 1: Problem Definition and Scope
Begin by clearly defining the performance issue:
Issue Classification:
□ Model loading/refresh performance
□ Report page loading performance
□ Visual interaction responsiveness
□ Query execution speed
□ Capacity resource constraints
□ Data source connectivity issues
Scope Assessment:
□ Affects all users vs. specific users
□ Occurs at specific times vs. consistently
□ Impacts specific reports vs. all reports
□ Happens with certain data filters vs. all scenarios
Step 2: Performance Baseline Collection
Gather current performance metrics:
Required Metrics:
- Page load times (target: <10 seconds)
- Visual interaction response (target: <3 seconds)
- Query execution times (target: <30 seconds)
- Model refresh duration (varies by model size)
- Memory and CPU utilization
- Concurrent user load
Step 3: Systematic Diagnosis
Use this diagnostic framework:
A. Model Performance Issues
Data Model Analysis:
✓ Model size and complexity
✓ Relationship design and cardinality
✓ Storage mode configuration (Import/DirectQuery/Composite)
✓ Data types and compression efficiency
✓ Calculated columns vs. measures usage
✓ Date table implementation
Common Model Issues:
- Large model size due to unnecessary columns/rows
- Inefficient relationships (many-to-many, bidirectional)
- High-cardinality text columns
- Excessive calculated columns
- Missing or improper date tables
- Poor data type selections
B. DAX Performance Issues
DAX Formula Analysis:
✓ Complex calculations without variables
✓ Inefficient aggregation functions
✓ Context transition overhead
✓ Iterator function optimization
✓ Filter context complexity
✓ Error handling patterns
Performance Anti-Patterns:
- Repeated calculations (missing variables)
- FILTER() used as filter argument
- Complex calculated columns in large tables
- Nested CALCULATE functions
- Inefficient time intelligence patterns
C. Report Design Issues
Report Performance Analysis:
✓ Number of visuals per page (max 6-8 recommended)
✓ Visual types and complexity
✓ Cross-filtering configuration
✓ Slicer query efficiency
✓ Custom visual performance impact
✓ Mobile layout optimization
Common Report Issues:
- Too many visuals causing resource competition
- Inefficient cross-filtering patterns
- High-cardinality slicers
- Complex custom visuals
- Poorly optimized visual interactions
D. Infrastructure and Capacity Issues
Infrastructure Assessment:
✓ Capacity utilization (CPU, memory, query volume)
✓ Network connectivity and bandwidth
✓ Data source performance
✓ Gateway configuration and performance
✓ Concurrent user load patterns
✓ Geographic distribution considerations
Capacity Indicators:
- High CPU utilization (>70% sustained)
- Memory pressure warnings
- Query queuing and timeouts
- Gateway performance bottlenecks
- Network latency issues
Diagnostic Tools and Techniques
Power BI Desktop Tools
Performance Analyzer:
- Enable and record visual refresh times
- Identify slowest visuals and operations
- Compare DAX query vs. visual rendering time
- Export results for detailed analysis
Usage:
1. Open Performance Analyzer pane
2. Start recording
3. Refresh visuals or interact with report
4. Analyze results by duration
5. Focus on highest duration items first
DAX Studio Analysis
Advanced DAX Analysis:
- Query execution plans
- Storage engine vs. formula engine usage
- Memory consumption patterns
- Query performance metrics
- Server timings analysis
Key Metrics to Monitor:
- Total duration
- Formula engine duration
- Storage engine duration
- Scan count and efficiency
- Memory usage patterns
Capacity Monitoring
Fabric Capacity Metrics App:
- CPU and memory utilization trends
- Query volume and patterns
- Refresh performance tracking
- User activity analysis
- Resource bottleneck identification
Premium Capacity Monitoring:
- Capacity utilization dashboards
- Performance threshold alerts
- Historical trend analysis
- Workload distribution assessment
Solution Framework
Immediate Performance Fixes
Model Optimization:
-- Replace inefficient patterns:
❌ Poor Performance:
Sales Growth =
([Total Sales] - CALCULATE([Total Sales], PREVIOUSMONTH('Date'[Date]))) /
CALCULATE([Total Sales], PREVIOUSMONTH('Date'[Date]))
✅ Optimized Version:
Sales Growth =
VAR CurrentMonth = [Total Sales]
VAR PreviousMonth = CALCULATE([Total Sales], PREVIOUSMONTH('Date'[Date]))
RETURN
DIVIDE(CurrentMonth - PreviousMonth, PreviousMonth)
Report Optimization:
- Reduce visuals per page to 6-8 maximum
- Implement drill-through instead of showing all details
- Use bookmarks for different views instead of multiple visuals
- Apply filters early to reduce data volume
- Optimize slicer selections and cross-filtering
Data Model Optimization:
- Remove unused columns and tables
- Optimize data types (integers vs. text, dates vs. datetime)
- Replace calculated columns with measures where possible
- Implement proper star schema relationships
- Use incremental refresh for large datasets
Advanced Performance Solutions
Storage Mode Optimization:
Import Mode Optimization:
- Data reduction techniques
- Pre-aggregation strategies
- Incremental refresh implementation
- Compression optimization
DirectQuery Optimization:
- Database index optimization
- Query folding maximization
- Aggregation table implementation
- Connection pooling configuration
Composite Model Strategy:
- Strategic storage mode selection
- Cross-source relationship optimization
- Dual mode dimension implementation
- Performance monitoring setup
Infrastructure Scaling:
Capacity Scaling Considerations:
- Vertical scaling (more powerful capacity)
- Horizontal scaling (distributed workload)
- Geographic distribution optimization
- Load balancing implementation
Gateway Optimization:
- Dedicated gateway clusters
- Load balancing configuration
- Connection optimization
- Performance monitoring setup
Troubleshooting Workflows
Quick Win Checklist (30 minutes)
□ Check Performance Analyzer for obvious bottlenecks
□ Reduce number of visuals on slow-loading pages
□ Apply default filters to reduce data volume
□ Disable unnecessary cross-filtering
□ Check for missing relationships causing cross-joins
□ Verify appropriate storage modes
□ Review and optimize top 3 slowest DAX measures
Comprehensive Analysis (2-4 hours)
□ Complete model architecture review
□ DAX optimization using variables and efficient patterns
□ Report design optimization and restructuring
□ Data source performance analysis
□ Capacity utilization assessment
□ User access pattern analysis
□ Mobile performance testing
□ Load testing with realistic concurrent users
Strategic Optimization (1-2 weeks)
□ Complete data model redesign if necessary
□ Implementation of aggregation strategies
□ Infrastructure scaling planning
□ Monitoring and alerting setup
□ User training on efficient usage patterns
□ Performance governance implementation
□ Continuous monitoring and optimization process
Performance Monitoring Setup
Proactive Monitoring
Key Performance Indicators:
- Average page load time by report
- Query execution time percentiles
- Model refresh duration trends
- Capacity utilization patterns
- User adoption and usage metrics
- Error rates and timeout occurrences
Alerting Thresholds:
- Page load time >15 seconds
- Query execution time >45 seconds
- Capacity CPU >80% for >10 minutes
- Memory utilization >90%
- Refresh failures
- High error rates
Regular Health Checks
Weekly:
□ Review performance dashboards
□ Check capacity utilization trends
□ Monitor slow-running queries
□ Review user feedback and issues
Monthly:
□ Comprehensive performance analysis
□ Model optimization opportunities
□ Capacity planning review
□ User training needs assessment
Quarterly:
□ Strategic performance review
□ Technology updates and optimizations
□ Scaling requirements assessment
□ Performance governance updates
Communication and Documentation
Issue Reporting Template
Performance Issue Report:
Issue Description:
- What specific performance problem is occurring?
- When does it happen (always, specific times, certain conditions)?
- Who is affected (all users, specific groups, particular reports)?
Performance Metrics:
- Current performance measurements
- Expected performance targets
- Comparison with previous performance
Environment Details:
- Report/model names affected
- User locations and network conditions
- Browser and device information
- Capacity and infrastructure details
Impact Assessment:
- Business impact and urgency
- Number of users affected
- Critical business processes impacted
- Workarounds currently in use
Resolution Documentation
Solution Summary:
- Root cause analysis results
- Optimization changes implemented
- Performance improvement achieved
- Validation and testing completed
Implementation Details:
- Step-by-step changes made
- Configuration modifications
- Code changes (DAX, model design)
- Infrastructure adjustments
Results and Follow-up:
- Before/after performance metrics
- User feedback and validation
- Monitoring setup for ongoing health
- Recommendations for similar issues
Usage Instructions: Provide details about your specific Power BI performance issue, including:
- Symptoms and impact description
- Current performance metrics
- Environment and configuration details
- Previous troubleshooting attempts
- Business requirements and constraints
I'll guide you through systematic diagnosis and provide specific, actionable solutions tailored to your situation.
FAQ
What does power-bi-performance-troubleshooting do?
Systematic Power BI performance troubleshooting prompt for identifying, diagnosing, and resolving performance issues in Power BI models, reports, and queries.
When should I use power-bi-performance-troubleshooting?
Use it when you need a repeatable workflow that produces text response.
What does power-bi-performance-troubleshooting output?
In the evaluated run it produced text response.
How do I install or invoke power-bi-performance-troubleshooting?
Ask the agent to use this skill when the task matches its documented workflow.
Which agents does power-bi-performance-troubleshooting support?
Agent support is inferred from the source, but not explicitly declared.
What tools, channels, or permissions does power-bi-performance-troubleshooting need?
It uses no extra tools; channels commonly include text; permissions include no explicit permission scopes.
Is power-bi-performance-troubleshooting safe to install?
Static analysis marked this skill as low risk; review side effects and permissions before enabling it.
How is power-bi-performance-troubleshooting different from an MCP or plugin?
A skill packages instructions and workflow conventions; tools, MCP servers, and plugins are dependencies the skill may call during execution.
Does power-bi-performance-troubleshooting outperform not using a skill?
About power-bi-performance-troubleshooting
When to use power-bi-performance-troubleshooting
When Power BI reports or dashboards are loading slowly or responding poorly. When DAX queries, model refreshes, or visual interactions need systematic performance diagnosis. When you need a structured checklist for identifying model, report, or capacity bottlenecks.
When power-bi-performance-troubleshooting is not the right choice
When you need the agent to directly access or administer Power BI, Fabric, gateways, or external monitoring systems. When the task is general BI dashboard creation rather than troubleshooting performance problems.
What it produces
Produces text response.