
Performance Optimization
- 71 installs
- 50 repo stars
- Updated June 18, 2026
- josiahsiegel/claude-plugin-marketplace
Helps with ai & agent building tasks.
About
performance-optimization is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted development.
- performance-optimization
- AI & Agent Building
- AI-coding skill
Performance Optimization by the numbers
- 71 all-time installs (skills.sh)
- +4 installs in the week ending Aug 2, 2026 (Skillselion tracking)
- Ranked #5,673 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Aug 3, 2026 (Skillselion catalog sync)
npx skills add https://github.com/josiahsiegel/claude-plugin-marketplace --skill performance-optimizationAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 71 |
|---|---|
| repo stars | ★ 50 |
| Last updated | June 18, 2026 |
| Repository | josiahsiegel/claude-plugin-marketplace ↗ |
What it does
Helps with ai & agent building tasks.
Files
Performance Optimization
Overview
Power BI performance depends on data model design, DAX efficiency, visual configuration, and infrastructure. This skill covers diagnostic tools, optimization techniques, and best practices for achieving fast, responsive reports.
Diagnostic Tools
Performance Analyzer (Built-in)
Enable in Power BI Desktop: View > Performance Analyzer > Start recording
| Metric | Meaning | Action if Slow |
|---|---|---|
| DAX query | Time to execute the DAX | Optimize measure, check filter context |
| Visual display | Time to render the result | Reduce data points, simplify visual |
| Other | Miscellaneous overhead | Usually minor, ignore unless dominant |
Workflow: 1. Start recording 2. Clear visual cache (click "Refresh visuals") 3. Interact with the report (change slicers, navigate pages) 4. Copy DAX query from slow visuals 5. Paste into DAX Studio for deeper analysis
DAX Studio
Free external tool for deep DAX performance analysis:
Key features:
- Execute DAX queries with timing
- Server Timings: shows Storage Engine (SE) vs Formula Engine (FE) time
- Query Plan: view logical and physical query plans
- VertiPaq Analyzer: model size and compression analysis
- All Queries trace: capture all queries sent by a report
Server Timings breakdown:
| Engine | What It Does | Optimization Target |
|---|---|---|
| Storage Engine (SE) | Scans VertiPaq data, retrieves rows | Reduce cardinality, columns scanned |
| Formula Engine (FE) | Evaluates DAX formulas | Simplify DAX, avoid nested iterators |
Ideal ratio: SE should be 80-90% of total time. High FE % means DAX is doing too much computation.
Common DAX Studio workflow: 1. Connect to Power BI Desktop (or XMLA endpoint) 2. Enable Server Timings (Query > Server Timings) 3. Paste the DAX query from Performance Analyzer 4. Execute and analyze timing breakdown 5. Look for:
- Many SE queries (indicates materialization issues)
- CallbackDataID in SE queries (data sent to FE for processing -- avoid)
- High FE time (DAX too complex)
- Large SE row counts (too much data scanned)
VertiPaq Analyzer
Analyze model size and compression in DAX Studio: Advanced > View Metrics
| Metric | What to Check | Target |
|---|---|---|
| Table size (bytes) | Identify largest tables | Reduce columns, remove unused |
| Column cardinality | High cardinality = poor compression | Reduce distinct values, group rare values |
| Column size | Disproportionately large columns | Remove or move to dimension |
| Dictionary size | Large string dictionaries | Shorten strings, use keys |
| Relationship size | Memory for relationship mapping | Normal, cannot optimize directly |
| Hierarchy size | Hidden auto date/time hierarchies | Disable auto date/time |
Data Model Optimization
Column Optimization
| Technique | Impact | How |
|---|---|---|
| Remove unused columns | High | Delete columns not used in any visual, measure, or relationship |
| Reduce column cardinality | High | Group rare values (bottom 5% into "Other") |
| Use integer keys | High | Replace text foreign keys with integer surrogates |
| Split date/time | Medium | Separate DateTime into Date (date) and Time (time) columns |
| Round decimals | Medium | Round to 2 decimal places instead of 15 |
| Avoid calculated columns | Medium | Use measures instead (query-time vs storage) |
| Disable auto date/time | Medium | Options > Data Load > uncheck |
| Remove text from facts | High | Move descriptions to dimension tables |
Relationship Optimization
- Use single-direction cross-filtering (avoid bidirectional)
- Enable "Assume Referential Integrity" for DirectQuery relationships
- Remove unused or redundant relationships
- Use integer key columns for relationships
Partition Strategy
For large tables, partition by date range:
- Historical partitions (yearly/quarterly) -- refresh rarely
- Recent partition (current month/week) -- refresh frequently
- Use incremental refresh to automate partition management
DAX Optimization
High-Impact Patterns
Use variables to avoid repeated calculations:
// BAD: Calculates [Total Sales] three times
Margin % = DIVIDE([Total Sales] - [Total Cost], [Total Sales])
// GOOD: Single calculation, reuse via variable
Margin % =
VAR Sales = [Total Sales]
VAR Cost = [Total Cost]
RETURN DIVIDE(Sales - Cost, Sales)Avoid FILTER with large tables in CALCULATE:
// BAD: Scans entire table
CALCULATE([Sales], FILTER(ALL(Products), Products[Category] = "Electronics"))
// GOOD: Column filter (optimized)
CALCULATE([Sales], Products[Category] = "Electronics")Avoid nested iterators:
// BAD: O(n^2) complexity
SUMX(Products,
SUMX(FILTER(Sales, Sales[ProductID] = Products[ProductID]),
Sales[Amount]))
// GOOD: Use relationship + simple aggregation
SUMX(Products, [Total Sales])Use DISTINCTCOUNT instead of COUNTROWS(DISTINCT(...)):
// BAD
COUNTROWS(DISTINCT(Sales[CustomerID]))
// GOOD
DISTINCTCOUNT(Sales[CustomerID])Avoid FORMAT() in measures (returns text, kills sort):
// BAD: Returns text, cannot sort
MonthLabel = FORMAT([Date], "MMMM yyyy")
// GOOD: Use a pre-computed column in the Date table for display
// And a numeric sort column for orderingMeasure Complexity Guidelines
| Complexity | Acceptable For | Performance Concern |
|---|---|---|
| Simple aggregation (SUM, COUNT) | Any visual | No |
| CALCULATE with column filter | Any visual | No |
| Single iterator (SUMX) | Most visuals | Watch row count |
| CALCULATE with FILTER(table) | Limited visuals | Yes, if table is large |
| Nested iterators | Avoid | Yes, always |
| CALCULATE inside SUMX | Use carefully | Context transition cost |
Visual Optimization
Reduce Visual Count
| Problem | Impact | Fix |
|---|---|---|
| 20+ visuals on one page | Each visual sends DAX query | Keep to 8-12 visuals per page |
| Visuals with many data points | Large result sets | Use Top N, aggregation |
| Many slicers | Each slicer change re-queries all visuals | Use "Apply" button |
Query Reduction
Enable query reduction features: 1. Report settings > Query reduction > Add Apply button to slicers -- users click "Apply" after all slicer changes 2. Reduce number of queries sent by > Disable cross-highlighting by default -- reduces inter-visual queries
Conditional Formatting
Avoid complex DAX-based conditional formatting on large tables. Use simple column references or measures with limited computation.
Advanced Capacity and Model Patterns
Detailed guidance for aggregations, composite models, Direct Lake performance, large dataset optimization (10GB+ semantic models), Power BI Desktop performance settings, Power BI Report Server tuning, and bookmark/filter optimization lives in references/advanced-capacity-patterns.md. Load that reference when tuning enterprise-scale models beyond basic DAX/model/visual improvements.
Performance Checklist
Data Model
- [ ] Star schema design (fact + dimension tables)
- [ ] Auto date/time disabled
- [ ] No unused columns
- [ ] Integer keys for relationships
- [ ] Single-direction cross-filtering
- [ ] Text columns only in dimension tables
- [ ] Calculated columns converted to measures where possible
- [ ] High-cardinality columns addressed
DAX
- [ ] Variables used for repeated expressions
- [ ] No FILTER on large tables in CALCULATE
- [ ] No nested iterators
- [ ] DISTINCTCOUNT preferred over COUNTROWS(DISTINCT(...))
- [ ] No FORMAT in measures used for sorting
- [ ] Measures return numeric types (not text)
Visuals
- [ ] 8-12 visuals per page maximum
- [ ] Apply button on slicers
- [ ] Top N applied on large tables
- [ ] Cross-highlighting minimized for heavy pages
- [ ] Conditional formatting uses simple expressions
Infrastructure
- [ ] Correct capacity size for workload
- [ ] Premium/Fabric for large models (>1GB)
- [ ] Gateway optimized (sufficient RAM, SSD, close to data source)
- [ ] Incremental refresh for large tables
- [ ] Aggregations for DirectQuery heavy queries
Direct Lake (if applicable)
- [ ] V-Order enabled on delta table writes
- [ ] Framing scheduled at appropriate frequency
- [ ] File/row-group counts within capacity guardrails
- [ ] Fallback behavior configured and monitored
- [ ] Calculated columns tested for fallback impact
Report Server (if applicable)
- [ ] Report server DB isolated from PBIRS process
- [ ] Sufficient CPU cores for peak concurrent users
- [ ] SSD storage with high IOPS for DB
- [ ] Report caching configured for popular reports
- [ ] Scale-out with NLB if >50 concurrent users
Additional Resources
Reference Files
- `references/dax-studio-walkthrough.md` -- Step-by-step DAX Studio analysis guide with query plan interpretation and latest DAX Studio features
Power BI Advanced Performance Patterns
Detailed guidance for aggregations, composite models, Direct Lake performance, large dataset optimization (10GB+ semantic models), Power BI Desktop performance settings, Power BI Report Server tuning, and bookmark/filter optimization. SKILL.md keeps diagnostic tools, model optimization, DAX optimization, visual optimization, and the checklist.
Aggregations
Pre-aggregated tables that Power BI queries instead of the detail table:
Setup
1. Create an aggregation table (Import) with pre-computed aggregates:
SELECT
ProductCategory,
CAST(OrderDate AS DATE) AS OrderDate,
SUM(Amount) AS TotalAmount,
COUNT(*) AS OrderCount
FROM Sales
GROUP BY ProductCategory, CAST(OrderDate AS DATE)2. In Power BI, set up aggregation mappings:
- Table > Manage aggregations
- Map:
TotalAmountsummarizationSumto detail columnSales[Amount] - Map:
OrderCountsummarizationCountto detail tableSales - Map:
ProductCategorygroup-by toSales[ProductCategory] - Map:
OrderDategroup-by toSales[OrderDate]
3. Hide the aggregation table from report view
Power BI automatically routes queries:
- Queries at aggregation grain -> hit the small Import table (fast)
- Queries at detail grain -> hit the DirectQuery detail table (slower but accurate)
Automatic Aggregations (Premium/Fabric)
Premium and Fabric capacities support automatic aggregation training:
- System analyzes query patterns
- Automatically creates and maintains agg tables
- No manual configuration required
- Enable in dataset settings
Composite Models
Mix Import and DirectQuery tables in one model:
| Table | Storage Mode | Why |
|---|---|---|
| Date dimension | Import | Small, used everywhere, fast |
| Product dimension | Import | Small, frequent filtering |
| Customer dimension | Import or Dual | Medium size |
| Sales fact | DirectQuery | Too large for Import |
| Aggregation table | Import | Pre-computed summaries |
Dual mode: Table exists as both Import and DirectQuery. Engine chooses based on query context:
- If all tables in query are Import, uses Import mode (VertiPaq)
- If any table requires DirectQuery, uses DirectQuery for dual tables too
Set storage mode: Model view > select table > Properties > Storage mode
Composite models with Direct Lake (2025 Preview):
- Mix Direct Lake tables with Import tables in a single model
- Direct Lake tables load from OneLake delta files; Import tables from traditional sources
- Enables extending a Fabric lakehouse model with additional reference data
- Monitor fallback behavior -- DL/SQL tables may fall back to DirectQuery under load
Direct Lake Performance
Direct Lake provides near-Import query speed without data duplication:
| Aspect | Guidance |
|---|---|
| V-Order | Enable in Spark notebooks/pipelines for optimal Parquet read performance |
| Framing frequency | Schedule frequent framing for near-real-time freshness (seconds cost) |
| Column count | Minimize columns -- each column still consumes memory when paged in |
| Guardrails | Monitor file/row-group counts per table (varies by F-SKU capacity) |
| Fallback (DL/SQL) | Set DirectLakeBehavior = DirectLakeOnly to block DQ fallback and force optimization |
| Fallback (DL/OL) | No DQ fallback -- queries fail if data cannot be served; optimize model size |
| Memory paging | Max Memory is soft limit -- excess paging degrades performance |
| Calculated columns | Supported but may trigger DQ fallback on DL/SQL; test impact |
| Modeling perf | Desktop 2025+ provides 50%+ improvement for live Direct Lake editing |
Large Dataset Optimization (10GB+ Models)
| Technique | Impact |
|---|---|
| Remove unused columns aggressively | High -- every column adds VertiPaq memory |
| Split DateTime into Date + Time | High -- reduces cardinality significantly |
| Use integer surrogate keys | High -- 4-byte integers compress far better than text |
| Reduce decimal precision | Medium -- ROUND to 2 places |
| Implement aggregation tables | High -- 100x fewer rows for summary queries |
| Use incremental refresh with partitioning | High -- only refresh changed partitions |
| Enable automatic aggregations (Premium/Fabric) | Medium -- system optimizes query routing |
| Consider Direct Lake for Fabric data | High -- eliminates Import refresh entirely |
| Disable auto date/time | Medium -- removes hidden tables |
| Archive cold data to separate model | Medium -- reduce active model footprint |
Power BI Desktop Performance Settings
| Setting | Location | Recommendation |
|---|---|---|
| Auto date/time | Options > Data Load | Disable for production models |
| Background data | Options > Data Load | Enable for faster development |
| Parallel loading | Options > Data Load | Enable for multi-table models |
| DirectQuery query timeout | Options > DirectQuery | Increase for slow sources (default 10 min) |
| Query reduction for slicers | Report settings | Enable "Add Apply button" |
| Auto recovery | Options > Data Load | Enable to prevent work loss |
| Report storage mode | Options > Preview | PBIR format for git-friendly development |
Power BI Report Server Performance Tuning
Report Server has different performance characteristics from the cloud service:
| Area | Guidance |
|---|---|
| CPU | Most critical resource at peak load -- add cores first |
| Memory/RAM | Increase allocated memory for better query caching |
| Storage | Use SSDs with high IOPS for the report server database |
| Database isolation | Host report server DB on separate machine from PBIRS |
| Scale-out | Deploy multiple PBIRS instances sharing one report server DB |
| Load balancing | Use NLB or Azure Traffic Manager across instances |
| High availability | Passive standby VM in another region for business continuity |
| Caching | Configure report execution caching for frequently viewed reports |
| Data source proximity | Place gateway/PBIRS close to data sources to reduce latency |
| Concurrent users | Monitor with performance counters; scale out at 50+ concurrent |
Bookmark and Filter Optimization
| Problem | Solution |
|---|---|
| Too many bookmarks loading data | Use report-level filters instead of bookmark-captured filters |
| Bookmarks causing full re-query | Minimize bookmark-captured visual states |
| Complex cross-page drillthrough | Use drillthrough instead of bookmarks for page navigation |
| Slicer cascades on page load | Set default slicer values to reduce initial query count |
DAX Studio Performance Analysis Walkthrough
Installation and Connection
Install
Download from https://daxstudio.org. Free, open-source tool by SQLBI.
Latest Features (2025-2026)
- UDF (user-defined functions) support in code completion and Functions tab
- Custom calendar support in code completion
- Parquet file export for query results
- Support for SSAS 2025
- Totals in Power BI Performance Data view
- RequestID tracing in server timings
- Enhanced tooltip display with event endtime and calculated duration
- Improved clipboard handling and UI enhancements
Connect to Power BI Desktop
1. Open Power BI Desktop with your report 2. Open DAX Studio 3. Select your PBIX file from the connection dialog (auto-detected)
Connect to Power BI Service (XMLA)
1. Requires Premium, PPU, or Fabric capacity 2. Connection string: powerbi://api.powerbi.com/v1.0/myorg/WorkspaceName 3. Initial Catalog: SemanticModelName 4. Authentication: Azure AD (Microsoft Entra ID)
Step 1: Capture the Slow Query
From Performance Analyzer
1. In Power BI Desktop: View > Performance Analyzer > Start recording 2. Click "Refresh visuals" to clear cache 3. Wait for report to render 4. Find the slow visual in the Performance Analyzer pane 5. Click "Copy query" on the slow visual 6. Paste into DAX Studio
Query format from Performance Analyzer
// Query for a bar chart visual
DEFINE
VAR __DS0Core =
SUMMARIZECOLUMNS(
'Product'[Category],
"SumAmount", CALCULATE(SUM('Sales'[Amount]))
)
VAR __DS0PrimaryWindowed =
TOPN(10, __DS0Core, [SumAmount], DESC)
EVALUATE
__DS0PrimaryWindowed
ORDER BY [SumAmount] DESCStep 2: Enable Server Timings
1. Query menu > Server Timings (or Ctrl+Shift+T) 2. This enables detailed engine-level timing
Server Timings Tab Columns
| Column | Meaning |
|---|---|
| Line | Query plan line number |
| Event Subclass | VertiPaq Scan (SE) or DAX Formula Engine (FE) |
| Duration | Time in milliseconds |
| CPU Time | CPU milliseconds consumed |
| Rows | Number of rows returned by this operation |
| KB | Data size in kilobytes |
| Query | The xmSQL query sent to Storage Engine |
Step 3: Analyze Server Timings
Reading the Results
After executing the query with Server Timings enabled:
Bottom of Server Timings pane shows totals:
- Total: Overall query time
- SE (Storage Engine): Time scanning data
- FE (Formula Engine): Time computing DAX
- SE Queries: Number of SE queries generated
- SE Cache: Number of SE queries served from cache
Interpreting Results
| Scenario | SE% | FE% | SE Queries | Diagnosis |
|---|---|---|---|---|
| Fast query | 90% | 10% | 1-3 | Healthy |
| Complex DAX | 30% | 70% | Few | DAX too complex, simplify |
| Materialization | 50% | 50% | Many (10+) | Too many SE queries, reorganize |
| Large scan | 95% | 5% | 1 but slow | Table too large, filter earlier |
| CallbackDataID | Varies | High | Has callbacks | Data sent to FE for processing |
Red Flags in SE Queries
CallbackDataID: When you see CallbackDataID() in an SE query, the Storage Engine is asking the Formula Engine to evaluate an expression for each row. This is extremely slow.
// BAD SE query with CallbackDataID
WITH $Expr0 := (PFCAST([Sales].[Amount] AS INT) + CallbackDataID())
SELECT $Expr0 FROM [Sales]Fix: Restructure DAX to avoid forcing SE to call back to FE. Common causes:
- Complex expressions in FILTER that cannot be pushed to SE
- Non-supported functions in VertiPaq scan
- Mixing row context and filter context incorrectly
Too many SE queries: Each SE query has overhead. More than 10-15 SE queries for a single visual indicates materialization issues.
Fix: Simplify the DAX, reduce the number of CALCULATE context changes, use variables.
Step 4: VertiPaq Analyzer
Access
Advanced menu > View Metrics (or connect and go to Advanced > View Metrics)
Model Summary
| Metric | What to Look For |
|---|---|
| Total Size | Overall model memory footprint |
| # Tables | Number of tables (less is often better) |
| # Columns | Total columns (remove unused) |
| # Rows | Data volume |
Table Analysis
Sort tables by size (descending) to find the biggest:
| Column | Target |
|---|---|
| Table Size | Fact tables should be largest, dimensions small |
| Rows | Verify expected row counts |
| Columns | Look for tables with too many columns |
| Dictionary Size | Large = high cardinality strings |
| Data Size | Actual compressed data |
Column Analysis (Most Important)
Sort columns by size (descending):
| Finding | Problem | Fix |
|---|---|---|
| Large text column in fact table | Destroys compression | Move to dimension |
| High cardinality column | Poor compression ratio | Group, reduce precision |
| Column not in any measure/visual | Wasted space | Remove |
| Multiple date columns, each with auto date table | Bloat | Disable auto date/time |
| Large dictionary, small data | Many unique strings | Hash, shorten, or group |
Compression Ratio
Compression Ratio = Data Size / Uncompressed Size| Ratio | Quality |
|---|---|
| 10:1 or better | Excellent (integer keys, low cardinality) |
| 5:1 to 10:1 | Good (typical dimensional data) |
| 2:1 to 5:1 | Poor (high cardinality or text-heavy) |
| <2:1 | Very poor (review column necessity) |
Step 5: Query Plan Analysis
Enable Query Plan
Query menu > Query Plan
Logical Query Plan
Shows what the engine plans to do at a high level:
| Operator | Meaning |
|---|---|
| Sum_Vertipaq | Simple sum, pushed to SE |
| GroupBy_Vertipaq | Grouping pushed to SE |
| Filter_Vertipaq | Filter pushed to SE |
| Sum_Formula | Sum evaluated in FE |
| CrossApply | Nested evaluation (potential perf issue) |
| AddColumns | Column computation |
| Cache | Caching intermediate result |
Physical Query Plan
Shows actual execution:
| Operator | Meaning |
|---|---|
| VertiPaq (scan) | SE scanning data -- good |
| SpoolLookup | Looking up cached data -- neutral |
| SpoolIterator | Iterating over spooled data -- watch count |
| Extend_Lookup | Extending result with lookup -- neutral |
Red flags in query plans:
- Many SpoolIterator nodes: Indicates excessive materialization
- CrossApply with large cardinality: Nested loops
- No VertiPaq scan operators: Everything in FE, model not being used efficiently
Common Optimization Recipes
Recipe 1: Slow CALCULATE with FILTER
Before (slow):
High Value Sales =
CALCULATE(
SUM(Sales[Amount]),
FILTER(Sales, Sales[Amount] > 1000)
)After (fast):
High Value Sales =
CALCULATE(
SUM(Sales[Amount]),
Sales[Amount] > 1000
)Why: Boolean filter generates optimized SE scan. FILTER(Sales,...) forces full table materialization in FE.
Recipe 2: SUMX with RELATED
Before (slow for large tables):
Revenue =
SUMX(Sales, Sales[Quantity] * RELATED(Products[Price]))After (faster):
-- Add Amount column in Power Query (source-side calculation)
-- Then use simple SUM
Revenue = SUM(Sales[Amount])Why: Pre-computing in Power Query avoids iterator overhead. If this is not possible, the SUMX version is acceptable but monitor SE timing.
Recipe 3: Counting with conditions
Before (slow):
Active Customers =
COUNTROWS(FILTER(Customers, Customers[Status] = "Active"))After (fast):
Active Customers =
CALCULATE(COUNTROWS(Customers), Customers[Status] = "Active")Why: CALCULATE with boolean filter is optimized. FILTER + COUNTROWS materializes the filtered table.
Recipe 4: Multiple IF conditions
Before (slow for many conditions):
Category =
IF([Amount] > 10000, "Premium",
IF([Amount] > 5000, "Gold",
IF([Amount] > 1000, "Silver", "Bronze")))After (marginally faster, more readable):
Category =
SWITCH(TRUE(),
[Amount] > 10000, "Premium",
[Amount] > 5000, "Gold",
[Amount] > 1000, "Silver",
"Bronze"
)Recipe 5: Year-over-Year with variables
Before (calculates measure twice):
YoY % =
DIVIDE(
[Total Sales] - CALCULATE([Total Sales], SAMEPERIODLASTYEAR(Date[Date])),
CALCULATE([Total Sales], SAMEPERIODLASTYEAR(Date[Date]))
)After (single PY calculation):
YoY % =
VAR CurrentSales = [Total Sales]
VAR PYSales = CALCULATE([Total Sales], SAMEPERIODLASTYEAR(Date[Date]))
RETURN DIVIDE(CurrentSales - PYSales, PYSales)Why: Variables are evaluated once and cached. Without VAR, PY calculation runs twice.
Benchmarking Protocol
1. Clear cache: In DAX Studio, clear the SE cache before benchmarking
- Right-click database > Clear Cache (requires admin on XMLA)
- Or disconnect and reconnect
2. Run warm: Execute query once (cold), then again (warm) 3. Compare: Focus on warm timings for user experience 4. Iterate: Make one change at a time, re-measure 5. Document: Record before/after timings for each optimization
VertiPaq Analyzer Updates (2025-2026)
VertiPaq Analyzer v2.1.3 (January 2026):
- Added support for functions metadata
- v2.1.2 (May 2025): Added support for multiple/empty selection DAX expressions in calculation groups
- Fully integrated into DAX Studio Advanced > View Metrics
Using INFO Functions for Model Analysis
As an alternative to VertiPaq Analyzer, use INFO DAX functions directly in DAX query view:
// Get storage statistics for all tables
EVALUATE INFO.STORAGETABLES()
// Get column-level storage details
EVALUATE INFO.STORAGETABLECOLUMNS()
// Get segment-level detail (most granular)
EVALUATE INFO.STORAGETABLECOLUMNSEGMENTS()These INFO functions return the same underlying data that VertiPaq Analyzer uses but are accessible directly from DAX query view without external tools.
Direct Lake Performance Diagnostics
For Direct Lake models, standard DAX Studio Server Timings still apply. Additional diagnostics:
| Metric | Where to Check | What to Look For |
|---|---|---|
| Fallback events | Fabric Capacity Metrics app | Frequent DQ fallback = model design issue |
| Framing duration | Refresh history via REST API | Should be seconds; long framing = delta log bloat |
| Memory paging | Capacity Metrics | Excessive paging = model too large for capacity |
| File/row group count | INFO.PARTITIONS() | Exceeding guardrails triggers fallback |
| Column transcoding | Server Timings | First query after framing may show cold-load time |
Optimization recipe for Direct Lake: 1. Enable V-Order writes in Spark notebooks 2. Compact small delta files (OPTIMIZE command) 3. Remove unused columns from gold layer tables 4. Monitor with INFO.STORAGETABLES() for memory footprint 5. Set DirectLakeBehavior = DirectLakeOnly to surface issues early