What drives Power BI capacity costs
Capacity cost is driven by a handful of things, and most of them are design decisions rather than usage.
Updated September 2026
- Refresh frequency and model size usually dominate the bill, not the number of people reading reports.
- Import, DirectQuery and hybrid have very different cost profiles for the same report.
- Non-production capacity can often be paused, which removes cost the reservation model cannot.
- Reserved capacity is cheaper per unit and cannot be paused. Match the commitment to the steady state, not the peak.
Fabric and Power BI capacity is billed by capacity units consumed over time. What consumes them is a short list, and most of it is decided at design time rather than by how many people open reports.
Refresh patterns
Usually the largest driver. Every scheduled refresh consumes capacity, and the cost is a function of how often, how much data, and how efficiently the model processes it.
The common findings are the same everywhere: datasets refreshing hourly to serve a report people look at once a day, full refreshes where an incremental refresh would move a fraction of the data, and refreshes for datasets nobody uses any more.
Incremental refresh on large tables is the single most effective change available in most tenants.
Model design
A model with unnecessary columns, high-cardinality text fields, and no thought to data types costs more to refresh and more to query than a well-shaped one holding the same information.
Calculated columns evaluated at refresh, relationships that force expensive joins, and measures written to be readable rather than efficient all show up in capacity consumption. This is ordinary modelling discipline and it pays continuously.
Query mode
Import, DirectQuery and hybrid have different profiles. Import consumes capacity at refresh and is cheap to query. DirectQuery consumes on every interaction and pushes load onto the source system instead.
Neither is right in general. What is wrong is choosing without knowing the pattern — DirectQuery against a heavily used report produces a steady load nobody predicted, and import on a very large dataset produces refresh costs that dominate the bill.
Content nobody uses
Reports and datasets that are still refreshing while nobody opens them. Usage data finds these quickly, and retiring them removes cost with no downside.
Concurrency and peaks
Capacity is a shared pool. When demand exceeds it, requests are smoothed or throttled, which users experience as slowness. The instinct is to buy the next size up; the better first step is to move refreshes out of the busy window, because peaks are frequently self-inflicted.
The commercial levers
Pause non-production capacity. Pay-as-you-go capacities can be paused, which stops the compute charge. Development and test environments rarely need to run overnight or at weekends, and this is often the fastest saving available.
Reserve for the steady state. Reserved capacity is substantially cheaper per unit than pay-as-you-go and cannot be paused. Reserve what runs continuously, and handle variable or temporary workloads outside the commitment.
Right-size deliberately. Sizing is usually chosen at go-live and never revisited. Usage patterns after a year look nothing like the projection, in both directions.
What to do first
Look at the refresh schedule before anything else. In most tenants there is a meaningful reduction available from refresh frequency, incremental refresh and retiring unused datasets — all design changes, none of which affect what anybody sees.
The practice behind it.
Capacity bill climbing?
We will find what is driving it, fix the design decisions behind it, and leave the model in a state that stays cheap.
