Know what refreshes today
Before you move anything, list every semantic model in scope with its refresh schedule, its data sources, the gateway or cloud connection it uses, who owns it and what depends on it: reports, dashboards, composite models, and dataflows upstream. The refresh history in each model's settings shows what actually runs and how long it takes, which is often different from what people believe.
Note whose credentials each model uses. A model owned by someone who has since left, or one that authenticates to its source as a named individual, will fail the moment that account changes. Fix ownership now, using a dedicated account or a service principal where your data sources support it, rather than finding out at cutover.
Look hard at upstream dependencies. A semantic model that reads from a dataflow will refresh without complaint against stale data if the dataflow has stopped, and the first sign is usually a user asking why the numbers have not moved.
Build the new path before you need it
Whether you are moving to a new workspace, capacity, tenant or gateway, the new refresh path has to exist before any live model uses it. That means the gateway installed and registered where it is needed, connections created with working credentials, and network access from the gateway to each data source tested by someone who can read a firewall log.
Test with a copy, not the live model. Publish a copy of a representative model to the target, bind it to the new connections and refresh it. If it fails, you have learned something at no cost to the people who use the reports.
Check gateway capacity as well as connectivity. A gateway that copes with today's schedule may struggle while old and new models both refresh through it, so watch its resource use during parallel running and consider a gateway cluster with more than one member for anything business critical.
Run old and new side by side
The safest pattern is parallel running. The existing model keeps its schedule and keeps serving reports while the migrated model refreshes on the new path. Compare row counts and key measures on both for several cycles. When they agree, move the reports.
Thin reports, connected to a shared semantic model rather than carrying their own, make this much easier, because you can rebind a report to a different model without republishing it, using the Power BI REST API or tools built on it. If each report embeds its own model, consider separating them during the migration. It is extra work now and much less work at every change afterwards.
Stagger the new schedules against the old ones so source systems are not queried twice at the same moment, and check that the target capacity can absorb the extra load while both are running.
Protect incremental refresh
Models with incremental refresh need particular care. Their history sits in partitions built up over time, and some ways of redeploying a model replace those partitions, which forces a full reload of history at the next refresh. On a large model that means a long refresh and heavy load on the source. If the source no longer holds the older data, it means history you cannot get back.
Republishing from Power BI Desktop over an existing model is the usual cause. For models with incremental refresh, deploy changes through the XMLA endpoint with a tool that can update metadata while leaving partitions in place. Confirm the behaviour against current Microsoft documentation before you rely on it, and take a backup first where your capacity supports one.
If a model has to be rebuilt from scratch in its new location, treat the first full refresh as an event: out of hours, with the source system owner aware, and with enough time before users need the figures.
Direct Lake changes the question
If the migration moves models to Direct Lake on Microsoft Fabric, refresh means something different. A Direct Lake model reads Delta tables in OneLake, and its refresh is a lightweight operation that points the model at the latest version of the data. The heavy work moves upstream, into the pipelines, notebooks or dataflows that load the lakehouse or warehouse.
The question then becomes whether the load finished before the model picked up the new data. Chain them: have the pipeline that loads the tables refresh the model as its final step, or check that the model's setting for keeping data up to date behaves the way you intend. Monitoring moves from the model's refresh history to the pipeline's run history.
Make failures visible
During a migration, refresh failures need to reach someone who will act on them that day. By default the notification goes to the model owner, which may be a migration account nobody reads. Add a monitored mailbox or group to the failure notification settings, and check refresh history daily until things settle.
Agree who responds. The migration team owns failures in the new refresh path; the model owner owns failures caused by data or logic; the source system owner owns availability. Write it down before go-live, because a failed refresh at six on a Monday morning is not the time to discover nobody thinks it is theirs.
Keep a simple log for the migration period: model, date, outcome, cause and fix. After a few weeks it tells you which failures were teething problems and which point to something that needs a proper repair.
Switching over and switching off
Once the new models have proved themselves, the switch is short. Work through it in order and do not skip the comparison.
Disable old schedules rather than deleting old models on day one. If a problem turns up a week later, you can switch the old refresh back on while you fix the new one, and users carry on with figures they trust.
- Confirm the new models have refreshed successfully for an agreed number of cycles.
- Compare key figures between old and new models refreshed at the same point.
- Rebind or repoint reports, dashboards and apps to the new models.
- Disable the old refresh schedules and keep the old models for a short fallback period.
- Delete the old models and remove unused connections and gateway data sources.