Get a Quote +90 553 510 56 56
Power BI 24 May 2026 · 8 min read

Power BI Performance Optimization: 10 Ways to Speed Up a Slow Report

If a Power BI report opens in 30 seconds, there's most likely a serious optimization opportunity in the model. 10 concrete tactics at the VertiPaq, DAX, data-model and visual layers.

Power BI Performance Optimization DAX
Th🐌 ÖNCE28.4s✨ SONRA3.2s%88daha hızlı3.5xdaha küçük10 OPTİMİZASYON TAKTIĞI✓ Gereksiz sütun sil✓ Yıldız şema✓ Single-direction✓ IF → SWITCH✓ FILTER → KEEPFILTERS✓ Ölçü > sütun✓ Görsel ≤ 12/sayfa✓ Kardinalite azalt✓ Aggregations✓ Incremental refresh

If a Power BI report makes users wait 30 seconds on two clicks, they'll stop opening that report after 3 weeks. Slowness isn't just a test of patience; it's the enemy of adoption. The good news: in 80% of slow reports, 3-5 concrete improvements can halve the load time. In this article we'll cover 10 practical optimization techniques, from the VertiPaq engine to visual design.

01. Remove Unnecessary Columns from the Model

Every column you import into the model takes up memory and is indexed. Columns added with the "might be useful" logic — uncompressible columns or high-cardinality text (customer name, address) — bloat the model 3-5x.

The principle: a column the report doesn't use shouldn't be in the model. It should be eliminated at the Power Query stage and not carried into calculated tables.

02. Split High-Cardinality Columns

A date-time column kept down to the microsecond is a disaster for VertiPaq. If you split it into separate date and time columns, both become low-cardinality and compression rises dramatically.

The same logic: if 2-3 decimal places are enough for full-precision prices, round off the rest. An invisible but critical memory gain.

03. Don't Use Column Calculations Instead of Measures

Calculation in DAX can be done in two places: a calculated column and a measure. The rule: prefer measures.

A calculated column is computed up front for each row and kept in the model (uncompressible, uses memory). A measure runs at query time, is filter-sensitive and doesn't increase the model size. The exception: a calculated column is needed for a dimension-based SLICER.

04. Replace IF Chains with SWITCH

Consecutive IF() calls are both hard to read and expensive to compute. The SWITCH(TRUE()) structure is both more readable and optimized by the engine:

Bad: IF([A]>10, "H", IF([A]>5, "M", IF([A]>1, "L", "N")))

Good: SWITCH(TRUE(), [A]>10, "H", [A]>5, "M", [A]>1, "L", "N")

A small change provides measurable speedup for large measures.

05. Use KEEPFILTERS Instead of FILTER

The CALCULATE + FILTER combination inside a measure is classic, but FILTER scans all rows of the table. For simple comparisons, KEEPFILTERS is more efficient:

Bad: CALCULATE([Sales], FILTER(Products, Products[Category] = "Electronics"))

Good: CALCULATE([Sales], KEEPFILTERS(Products[Category] = "Electronics"))

DAX Studio's Query Plan tool can be used to measure the difference.

06. Build a Star Schema (Avoid Snowflake and Flat)

The star schema is ideal for VertiPaq's compression math. Snowflake slows things down; a flat model blows up memory. This is the fundamental decision in model setup.

For detail, see our article Power BI Data Model: The Star Schema.

07. Avoid Bidirectional Relationships

Making relationships two-way looks tempting but forces the query engine into complex joins. A single-direction relationship is both faster and more predictable.

In most scenarios where bidirectional seems necessary, two-way behavior can be triggered locally within a measure using CROSSFILTER(); there's no need to make it permanently bidirectional in the model.

08. Limit the Number of Visuals

Having 20+ visuals on a page is tiring for both the user and the query engine. Each visual turns into a separate query; everything visible on screen is computed in parallel.

The rule: 8-12 visuals on a page is optimal. Move the rest to sub-pages or drill-throughs.

09. Use Aggregations

Even if you have a billion-row fact table, detail isn't always needed. The overview is usually content with a monthly total. The Aggregations feature pre-computes frequently used totals and keeps them in memory; it answers from this summary table instead of the main fact table.

10x-100x speedup is possible, but the setup requires care; every measure must delegate correctly across every dimension.

10. Use Incremental Refresh

Pulling a million-row fact table from scratch on every refresh is unnecessary. Incremental refresh only refreshes the last X days' data; old partitions stay in cache.

In a table with monthly partitions, refresh time drops from hours to minutes. Available with a Power BI Premium (and Pro Fabric) license; support in Power BI Pro is limited.

We can help you with this

Explore our Power BI solution

You can book a free consultation call to get detailed information.

View the Page Get a Quote
Power BI articles

Other Articles on This Topic

Power BI

Power BI Data Model: The Anatomy of a Correct Setup with the Star Schema

26 June 2026 · 9 min read
Power BI

An Introduction to Business Intelligence with Power BI: A Getting-Started Guide

20 June 2026 · 8 min read
All articles