What it does
An incremental refresh policy tells the service to partition a table by date and refresh only the recent partitions, keeping older data in place. Optionally it adds a DirectQuery partition on the end so the most recent changes appear without a refresh at all — that combination is a hybrid table.
Key facts
- The policy is driven by two reserved, case-sensitive Power Query parameters,
RangeStartandRangeEnd, both of date/time type. You filter the table's date column with them usingTable.SelectRows, not the standard filter UI. - Two settings define the policy: how far back to archive, and how far back to incrementally refresh. Both roll forward on every refresh. Partitions that fall out of the archive window are dropped entirely — the rolling window pattern.
- Incremental refresh is supported for Power BI Premium, Premium Per User, Power BI Pro and Power BI Embedded models. The Get the latest data in real time with DirectQuery option is Premium, PPU and Embedded only, and the model has to be published to a Premium workspace.
- Query folding has to carry the
RangeStart/RangeEndfilter to the source. If it doesn't fold, the mashup engine may pull every row and filter locally, which defeats the entire point. Desktop's verification is reliable for SQL-based sources and warns you when it can't confirm. - If real-time DirectQuery is enabled, non-folding transformations can't be used at all.
- All partitions, Import and DirectQuery, must query a single data source.
- Only refresh complete days is optional normally and mandatory when real-time DirectQuery is on.
- Refresh operations run under UTC unless a time zone is configured under Refresh settings, which affects what "complete day" means.
- Detect data changes uses a separate audit-style date/time column — not the partitioning column — and only refreshes periods whose maximum value has moved. That column is persisted and cached in memory.
- A hybrid table can have many Import partitions but only one DirectQuery partition. Set related dimension tables to Dual so the DirectQuery partition generates sensible native queries.
When to use / skip
Add a policy once full refresh stops fitting comfortably in the window, or once it's putting real load on a source system somebody else owns. Below tens of millions of rows it's usually premature — you're adding parameters, folding constraints and a one-way publish step to solve a problem you don't have yet. The real-time DirectQuery option is a narrower call: take it when the business genuinely needs today's transactions inside an otherwise imported model, and accept that you've now got DirectQuery's performance characteristics on the live partition.
Configuration decisions
- The archive period and the refresh period, which together decide partition granularity and how much gets reprocessed each night.
- Whether Detect data changes is worth the extra column, given it has to be persisted in memory.
- Whether the real-time DirectQuery partition is needed at all, or whether a more frequent refresh gets close enough.
- Whether large semantic model storage format goes on before the first refresh, if the model is heading past 1 GB.
- Whether the client needs XMLA-level partition control — bootstrapping, refreshing backdated partitions — which changes the tooling and licensing conversation.
Gotchas
- Once you publish a model with an incremental refresh policy, you can't download the .pbix back. Your source control story has to exist before the first publish, not after.
- The first refresh in the service is slow — partitions get created, history loads, relationships and calculated objects rebuild. Do it manually so you can watch it, and don't schedule it into a busy window.
- Folding silently failing is the classic failure. It doesn't error; the refresh just takes forever or runs out of memory on the gateway. Verify with Power Query Diagnostics or a source-side trace rather than trusting the dialog.
- UTC catches out anyone east or west of it. A refresh at 04:00 local isn't a refresh at 04:00 UTC, and "complete days" shifts accordingly.
- If you define policies on several tables, they all share the same
RangeStartandRangeEndparameters even where the periods differ. - Detect data changes on a high-cardinality timestamp column adds real memory cost. Reduce the precision or persist only the maximum value.
Consultant notes
- Do the folding proof before you promise the refresh window. Everything else in the design depends on it.
- Push for a proper date/time or
yyyymmddinteger column in the source early. Retrofitting one into a warehouse mid-project is somebody else's sprint. - Explain the rolling window to the business owner in plain terms: data older than the archive period disappears from the model. People assume Power BI keeps everything forever.
- If the client wants real-time, ask what decision changes in the next hour because of the number. Usually the honest answer moves the requirement to "refresh at lunchtime too".
- Get the .pbix into Git or PBIP format before the first publish, given the one-way download.
Recheck the supported plans line if the Premium-only gate on real-time DirectQuery partitions moves onto Fabric F SKUs wording.