What Power BI actually is inside Fabric#

Power BI is Microsoft's business analytics platform for turning data into insights, and inside Fabric it's the workload that supplies the analytics and visualization layer on top of everything else the platform stores and computes [S8]. Existing Power BI content carries into Fabric without any migration step — users sign in with the same accounts they always used, the interface stays familiar, and Fabric simply layers additional capabilities underneath [S8].

Underneath every report sits a semantic model — Power BI's current name for what used to be called a dataset — and that model is the thing reports, dashboards, and apps are all ultimately built from; a single model is free to blend several data sources together [S1]. Structurally, the vast majority of these models are Analysis Services tabular models under the hood, with streaming models as the one exception [S2].

Two audiences use the service in fundamentally different ways. Report authors design, assemble, and ship content, while everyone else opens that content to filter, drill, and make decisions from it [S1]. That split matters because it shapes almost everything else: how content gets packaged, who needs which license, and what a capacity is actually paying for.

A report itself is a bounded artifact — a set of pages built around interactive visuals that all pull from a single semantic model, usually organized to answer a related set of business questions [S1]. A dashboard is a different shape entirely: one screen of tiles that can be stitched together from several different reports and models at once, built for at-a-glance monitoring rather than deep exploration [S1]. When a team wants to hand a coherent bundle of dashboards and reports to a broad audience, the recommended move is to package it as a Power BI app rather than sharing each item separately — apps exist precisely so designers aren't stuck distributing content one piece at a time [S1].

Everything you see in a report traces back to one thing: the semantic model [S1].

Everything above runs on top of a capacity: a reserved block of compute assigned to Power BI content. Only the larger tiers unlock free-license viewing — Premium's P SKUs, or an F64-and-up Fabric capacity — while creating and sharing Power BI content outside a personal My Workspace always requires at least one Pro or Premium-Per-User (PPU) licensed user, regardless of capacity size [S9]. Copilot inside Power BI has a much lower capacity floor than that free-viewing tier, needing only an F2-and-up Fabric capacity or Premium P1 and above [S1]. Copilot itself ships turned on but is inert without that qualifying capacity behind it; once it's live, it acts as an assistant for drafting reports, exploring data, and summarizing results in plain language [S1].

Where the data underneath a report actually lives#

Workspaces are the containers that hold all of this. They're shared spaces where authors keep their dashboards, reports, and models together, access is gated through Admin/Member/Contributor/Viewer roles, and — because Fabric workspaces are multi-purpose — the same workspace can just as easily hold a lakehouse or a notebook alongside the Power BI items [S1].

A lakehouse is one of the more common places that data starts its journey before it reaches a report. It stores structured and unstructured data side by side in one place and lets either Apache Spark or T-SQL query that same data directly, with no separate copy step needed to hand data between the two engines [S3]. Every managed table inside it is stored as Delta, which is what buys ACID guarantees, enforced schema, and the ability to query a table as of an earlier point in time [S3]. Storage inside a lakehouse splits cleanly into a governed Tables area, reserved for Delta, and a Files area for anything unstructured or not yet in Delta format [S3].

Data typically arrives in that Tables area through one of several routes — Spark notebooks, pipeline copy activities, compiled Spark job definitions, low-code Dataflows Gen2, or a OneLake shortcut that simply points at data living somewhere else without duplicating it [S3]. Landing new data as Delta inside that managed area triggers Fabric's own bookkeeping: the platform inspects what arrived, catalogs its schema and physical layout (typing, compression, partition scheme), and makes it visible in the metastore — the practical upshot is a data engineer never hand-writes a CREATE TABLE statement to make a new Delta drop queryable [S3]. Every new lakehouse arrives with a T-SQL query surface already attached, generated automatically the moment the lakehouse is created; it's built for browsing and querying, not for the broader transactional capabilities a full warehouse item provides [S3]. Only Delta-format tables show up through that endpoint, including ones reached via a shortcut; anything still in Parquet or CSV needs converting first [S3]. A lakehouse and a warehouse share the exact same underlying SQL engine and both write Delta into OneLake, so picking between them really comes down to workload shape: lean on the lakehouse when Spark and unstructured data dominate, and reach for the warehouse when the job needs T-SQL-first tooling and multi-table transactional guarantees the lakehouse can't offer [S3]. A pattern that shows up often in practice is running both together — Spark handles the raw-to-curated transformation (often as a medallion layering), and the warehouse then exposes the finished, curated tables to SQL-oriented reporting teams [S3].

Worth noting: as of September 5, 2025, creating a lakehouse no longer automatically spins up a default semantic model, and Fabric finished decoupling any pre-existing default models from their parent lakehouse into standalone models by the end of November 2025 [S3].

Power BI in Fabric: reports and apps consuming semantic models across Import, DirectQuery, and Direct Lake storage modes, with governed consumption over OneLake

Choosing how a semantic model stores its data#

A model in Power BI Desktop can be built in one of three storage modes, and the difference between them comes down to a single question: does the data get copied into the model, or does it stay put and get queried live [S2]? Import copies everything in and caches it in a heavily compressed in-memory structure so queries return fast, but a fresh Import model tops out at 1 GB unless the large storage format is switched on [S4]. Because Import is a snapshot, it depends entirely on scheduled or manual refresh to stay current; DirectQuery instead forwards every query straight to the source system, trading some speed for always-current results [S2]. Both Import and DirectQuery need an on-premises data gateway the moment their source isn't directly internet-reachable [S2]. Composite mode is the third option — a way of mixing storage strategies within one model rather than committing entirely to one or the other [S2].

Beyond the model itself, reports don't have to originate the connection: a live connection lets a report point at an already-published model without altering it, and that's a genuinely different mechanism from opening and editing the model live in Desktop, or from building a fully local model with its own bundled Import or DirectQuery tables [S5]. Live-connecting only requires Build permission on the target model, and authors can attach report-level measures to a live-connected report without ever touching the shared model's own measures [S5]. Reports can be spun up from a surprising number of starting points too — the OneLake catalog inside Desktop, a right-click in the workspace, the model's own details page, or the create-report shortcut in web modeling [S5]. And a model's usefulness doesn't stop at interactive reports: the same model can back paginated reports, freeform data explorations, one-off DAX queries, and Excel pivot tables refreshed live through Analyze in Excel [S5].

It's also possible to point Power BI at a model that isn't hosted in the service at all — a live connection can reach an on-premises SQL Server Analysis Services model or an Azure Analysis Services model instead, with the viewer's own identity enforcing what data they can see [S2]. If an organization already has years of modeling logic sunk into an on-premises or Azure Analysis Services cube, pointing Power BI at it live is the sanctioned shortcut — rebuilding that same logic natively inside Power BI is explicitly not the recommended path [S2].

Note

Row-level security in a semantic model comes in two flavors: dynamic rules that filter rows based on who's actually viewing, and static rules that apply the same fixed filter to everyone assigned to a role [S2].

Ownership matters more than it might seem. Only the model's owner can change its gateway or cloud-connection settings — everyone else sees those settings but can't touch them — though ownership can be reassigned programmatically, which matters when the original author leaves the organization [S2]. And what actually determines how much capacity a given model consumes isn't one number but a combination of factors: where it's hosted, which storage mode it uses, whether a gateway sits in the path, how much data gets imported, and how often (and how) it refreshes [S2]. The gateway itself is versioned against Power BI Desktop's own release cadence — Microsoft aligns each on-premises data gateway release with a specific Desktop version so that queries a gateway executes on refresh run under the same runtime and logic as that paired Desktop build, rather than drifting between the two [S13].

Direct Lake: reading OneLake without copying it#

Direct Lake is the storage mode built specifically to let a semantic model read Delta tables straight out of OneLake, loading individual columns into memory only as queries actually need them rather than importing the whole table up front [S6]. That's a meaningfully different tradeoff from Import (which copies everything ahead of time) and DirectQuery (which never caches anything) — Direct Lake sits in between, keeping most of DirectQuery's freshness while borrowing much of Import's speed.

There are actually two distinct flavors, and picking the right one depends on what the workload needs. Direct Lake on OneLake talks to OneLake directly, which brings OneLake's own security model, a broader set of modeling features, and generally faster queries [S7] [S6]. Direct Lake on SQL routes through the SQL analytics endpoint instead, and it's the flavor to reach for when the endpoint's own security rules need to apply under a delegated identity, or when the model needs the option to fall back to DirectQuery [S7] [S6]. Desktop and the Power BI service only ever create the OneLake flavor directly — the only place that offers a choice between the two is the "new semantic model" flow launched from the SQL analytics endpoint page itself [S7]. That creation dialog isn't arbitrary about its default either: if the underlying SQL endpoint is running in user identity mode it defaults to Direct Lake on OneLake, and if the endpoint is in delegated identity mode it defaults to Direct Lake on SQL instead [S7].

Consuming a Direct Lake model requires nothing special on the client side — reports, explorations, and DAX queries all work against it exactly as they would against any other semantic model [S5]. But the internal read path genuinely differs by flavor. On the OneLake flavor, the model's shared expression points at the OneLake storage location itself, and OneLake's own APIs handle schema discovery, security enforcement, and loading the data — the SQL endpoint is never involved [S7]. On the SQL flavor, that shared expression instead points at the SQL analytics endpoint, but the endpoint's role is narrower than it sounds: it's consulted only to resolve schema and enforce security, while the actual column data still streams straight out of OneLake unless a query has to drop into DirectQuery fallback [S7].

Warning

Building a Direct Lake on SQL table over a SQL view rather than a base table forces every single query against it into DirectQuery fallback — a real performance trap, since fallback is generally slower than native Direct Lake reads [S7].

sql
-- Wrong: table sourced from a SQL view forces every query to DirectQuery fallback
CREATE VIEW dbo.vw_sales_curated AS
SELECT s.*, c.CustomerSegment
FROM dbo.Sales s
JOIN dbo.Customers c ON s.CustomerId = c.CustomerId;
-- Direct Lake on SQL model built against vw_sales_curated loses Direct Lake reads entirely

-- Right: model the join into a materialized Delta table instead, then point Direct Lake at the base table
CREATE TABLE dbo.SalesCurated
AS SELECT s.*, c.CustomerSegment
FROM dbo.Sales s
JOIN dbo.Customers c ON s.CustomerId = c.CustomerId;
-- Direct Lake on SQL model built against SalesCurated stays in native Direct Lake mode

Direct Lake on OneLake also supports composite modeling, which opens up a genuinely useful pattern: keep an enormous fact table in Direct Lake so it never pays a refresh cost, while letting smaller dimension tables sit in Import or DirectQuery within that same model [S7].

Telling the two flavors apart#

If you inherit a model and need to know which Direct Lake flavor you're looking at, there are two reliable tells. Inside TMDL view, check the M expression behind the table: the OneLake flavor uses the Azure Data Lake Storage connector, while the SQL flavor uses either the SQL Server connector or the OneLake.SqlAnalytics connector [S7]. Working over XMLA instead, a Direct Lake model announces itself through a database compatibility level of 1604 or above, partitions whose mode is explicitly directLake, and those partitions referencing a shared expression as their data source [S7].

Direct Lake models aren't limited to browser-based authoring, either — XMLA-compliant tooling like SSMS 19.1 and newer, various community tools, or Fabric notebooks scripting against semantic-link and semantic-link-labs can all build and modify them programmatically [S7].

Copilot-era authoring: AI-assisted DAX, AI-ready models, and the Q&A transition#

The biggest shift in how Power BI is authored recently isn't a new storage mode — it's how much of the modeling and report-building work Copilot now takes on directly. Three changes matter here: DAX generation inside Desktop, a formal way to prepare a model so Copilot answers it well, and the retirement of the older Q&A natural-language feature in favor of Copilot.

Note

The Copilot-facing claims in this section come from an independent practitioner write-up rather than Microsoft Learn directly. Where that write-up states something as Microsoft's own documented behavior — capacity requirements, prompt limits, sovereign-cloud support, and the Q&A deprecation — the underlying limit has been independently cross-checked against Microsoft's documentation; treat everything else in this section as a lower-trust secondary source and confirm against Microsoft Learn before relying on it operationally.

AI-assisted DAX authoring#

A Copilot-based assistant is available inline in Power BI Desktop's DAX query view, invoked via a keyboard shortcut, to draft or edit DAX expressions from natural-language prompts [S10]. It isn't limited to writing formulas from scratch — Copilot can also proactively suggest new measures based on the model's existing structure and auto-generate plain-language descriptions of measures that already exist [S10]. Demonstrated prompt-to-DAX patterns include year-over-year growth built with DATEADD guarded by IF/ISBLANK, Top-N ranking with RANKX, and rolling averages combining DATESINPERIOD with AVERAGEX [S10].

Ask for blank-safe logic explicitly, don't assume it. Including an explicit qualifier such as "blank-safe" in the generation prompt is the reliable way to get BLANK()/ISBLANK()-guarded time-intelligence measures back, rather than a version without those guards [S10].

csharp
Weak prompt: "Write a DAX measure for year-over-year sales growth"
  -> may omit BLANK()/ISBLANK() handling for periods with no prior-year data

Better prompt: "Write a blank-safe DAX measure for year-over-year sales growth
               using DATEADD, guarding against ISBLANK on the prior period"
  -> returns a measure that checks ISBLANK() before dividing, avoiding /0 and stray BLANK rows

Coming soon — the exact generated DAX text depends on a specific model schema this article doesn't have grounded claims for; the pattern above is a paraphrase of the documented prompt strategy, not a literal transcript [S10].

Two limits are worth knowing before leaning on this assistant operationally. First, for Import-mode models the assistant's visibility into the underlying data is limited to sampled minimum/maximum values per column rather than the full value distribution — a real constraint on how well it can validate generated logic against the data's actual shape [S10]. Second, newly released DAX functions aren't reliably recognized by the assistant for some period after they ship, so don't assume day-one support for brand-new DAX syntax [S10].

Copilot for Power BI generally — including this DAX assistant — only runs on a paid Fabric or Power BI Premium capacity; it is not supported on trial capacities, free SKUs, or a Pro license alone, and prompts across Copilot's surfaces are capped at 10,000 characters [S10] [S11]. It's also unavailable in sovereign cloud environments, per Microsoft's documentation, because of GPU availability constraints there [S10].

Preparing a model to be AI-ready#

Power BI's Prep data for AI dialog is a single entry point that exposes three separate preparation tools for a semantic model: an AI data schema, free-text AI instructions, and verified answers [S11]. Treat these as the modeling-layer equivalent of documentation — Copilot answers only as well as the model tells it to.

Rename and describe deliberately, not exhaustively. Configuring the AI data schema means renaming cryptic technical field names into business-friendly terms, adding descriptions to the measures and columns that actually get asked about, supplying business-vocabulary synonyms, and flagging fields as analytical focus points such as date dimensions or core KPIs [S11]. The antipattern here is documented explicitly: writing a description for every single column indiscriminately, instead of focusing on the fields that matter for common questions, produces shallow descriptions that don't move the needle on Copilot's answer quality [S11].

sql
Antipattern: auto-generate a one-line description for all 140 columns in the model
  -> shallow, generic text; Copilot answer quality does not improve

Better: describe the ~12 columns and measures that show up in real user questions
  (TotalSales, CustomerSegment, FiscalQuarter...), skip surrogate keys and audit columns
  -> Copilot has focused, business-meaningful context where it matters

Free-text AI instructions cover a different layer — business terminology and acronyms, temporal context like fiscal-year definitions, default filtering assumptions, and disambiguation rules for concepts that span multiple tables [S11]. A verified answer, meanwhile, is set by selecting a report visual in edit mode, marking it as a verified answer from its context menu, and then defining several trigger-phrase variants so Copilot recognizes both the exact question and paraphrased versions of it [S11].

Wait before you retest. After applying Prep data for AI changes, give the model some minutes before retesting Copilot — updates aren't guaranteed to be reflected in answers immediately [S11]. A model-level diagnostic surfaced on Copilot answers, described as "How Copilot Arrived At This," helps authors troubleshoot why a given response was generated the way it was [S11]. Using this Copilot surface requires the model to sit in a workspace backed by paid Fabric or Power BI Premium capacity, plus a tenant admin having enabled Copilot for the organization [S11].

The Q&A-to-Copilot transition#

Per Microsoft's own documentation, the classic Q&A visual and related Q&A natural-language experiences in Power BI are being deprecated, with Microsoft recommending Copilot as the successor for natural-language querying [S11]. Inference: exact retirement dates for Q&A were not present in the verified claims this article draws from; if a firm decommission date matters for your planning, confirm it directly against Microsoft's Q&A documentation before treating December 2026 as settled. Any verified-answer and AI-instruction work invested through Prep data for AI carries forward into that Copilot-based replacement rather than being Q&A-specific effort that gets thrown away.

Source-controlling reports: the PBIR format#

Separately from the Copilot changes, Power BI has also changed how a report's own metadata is stored on disk, which matters directly for teams source-controlling Power BI Projects (.pbip).

PBIR stores a report's metadata as a folder of individual JSON files — one per page, visual, and bookmark — replacing the legacy format's single combined report.json blob [S12]. Inference: PBIR grounding here comes from an independent practitioner source rather than Microsoft Learn; treat the mechanics as directionally reliable but confirm exact file layout against Microsoft's own PBIR documentation before automating around it.

Adopt PBIR specifically for the Git diff improvement, and verify that's actually why you're doing it. Because PBIR splits report metadata into many small JSON files, changing a single visual now produces a small, line-level Git diff instead of the large, unreadable diff the legacy single-blob format produced [S12]. That's the practical payoff — code review on a report change becomes tractable instead of "trust the whole blob changed correctly."

sql
Legacy format: one report.json blob, ~4,000 lines
  -> moving one textbox changes a diff spanning hundreds of unrelated-looking lines
  -> reviewers cannot tell what actually changed

PBIR format: one JSON file per visual/page/bookmark
  -> moving one textbox changes ~5 lines in one visual's JSON file
  -> reviewers see exactly what moved

PBIR only changes the report layer, though — the semantic model layer (tables, relationships, measures) continues to live separately in TMDL inside the same .pbip project, so adopting PBIR does not by itself change how the semantic model portion is source-controlled [S12]. PBIR is also explicitly an internal storage-format change: it does not replace the .pbix file extension or file type, which remains the primary distributable report file [S12].

Warning

Upgrading a Power BI Project from the legacy report format to PBIR is a one-way operation with no built-in downgrade path — keep a backup before upgrading [S12]. Older or uncertified custom visuals may also fail to serialize correctly under PBIR while the format was in preview, which is worth checking before committing a report to the new format [S12].

Inference: at the time this practitioner source was written, PBIR was enabled through two separate Desktop preview-feature toggles, with signals that the opt-out toggles would be removed at general availability [S12] — treat the current toggle state and GA timing as something to verify against Desktop's current release notes rather than as a stable fact.

How it works / best practices#

Pick the large semantic model storage format deliberately, not just for size. The default 1 GB Import ceiling is a memory limit, not a hard product cap — switching on the large storage format raises that ceiling to whatever the hosting Fabric capacity (or an admin-set maximum) allows, and it's available across Fabric F, Premium P, Embedded A, and Premium Per User [S4]. Desktop's own upload limit stays fixed at 10 GB regardless — a model only grows past that inside the service, usually via an incremental refresh policy adding data over time [S4]. The reason to flip this toggle isn't only "the model is big," though: XMLA write tools benefit from the large format's better write performance even against a genuinely small model [S4].

python
Model is 800 MB but XMLA tools write to it nightly
  -> without large format: slower XMLA writes regardless of model size
  -> with large format enabled: same model, materially faster XMLA writes

Watch the memory headroom before triggering a full refresh on a large model. As a rule of thumb, once a model's size gets into the same neighborhood as half the hosting capacity's total memory — think a model in the low-teens of GB sitting on a 25 GB capacity — a full reload during refresh can tip the capacity into an out-of-memory failure [S4]. Swapping in narrower, partition-scoped refresh calls (enhanced refresh REST API, or XMLA directly) avoids ever asking the engine to hold two full copies of the model in memory at once [S4].

sql
Antipattern: nightly full refresh pushes a large model past capacity headroom
  -> risk of out-of-memory failure mid-refresh

Better: enhanced refresh REST API call scoped to only the partitions that changed
  POST /v1.0/myorg/groups/{groupId}/datasets/{datasetId}/refreshes
  { "type": "ClearValues|Full", "objects": [ { "table": "Sales", "partition": "Sales_2026Q3" } ] }

Reach for an existing enterprise Analysis Services model instead of rebuilding it. When a mature tabular model already sits behind SSAS or Azure Analysis Services, treat it as a source to connect to live, not a spec to re-implement — Power BI's own guidance favors preserving that prior modeling work over duplicating it [S2].

Internals#

Architecture & design#

The layering here is deliberately consistent: a capacity supplies the compute, a workspace groups the content and its access controls, and inside that workspace a semantic model — usually Delta on OneLake underneath — is the single point every report, dashboard, app, paginated report, and Excel connection ultimately reads from [S1] [S2]. Direct Lake sits at the architectural seam between that model layer and OneLake itself: rather than Power BI owning a private copy of the data (Import) or bouncing every query back to a separate source system (DirectQuery), Direct Lake lets the model read the same Delta files that Spark and T-SQL are already reading, with no separate copy and no data-movement step in between [S6] [S3]. The two Direct Lake flavors are really a choice about which security and discovery layer sits in that seam — OneLake's own APIs directly, or the SQL analytics endpoint acting as a narrower schema-and-security gatekeeper in front of it [S7].

Copilot and the AI-readiness layer sit architecturally on top of that same semantic model rather than beside it: the AI data schema, AI instructions, and verified answers are all metadata attached to the existing model object, not a separate service with its own data path [S11]. That's also why Copilot's capacity requirement piggybacks on the same paid-capacity gate as the rest of Power BI's premium features, rather than introducing a new licensing dimension [S11] [S10].

How it works internally#

Decision diagram: choosing a Power BI semantic model storage mode — Import vs DirectQuery vs Direct Lake, branching on freshness need and data location; a Direct Lake on OneLake vs Direct Lake on SQL sub-decision with DirectQuery fallback triggers; a query-speed/freshness/footprint/operational-lever tradeoff scorecard; and guardrails covering Block Public Internet Access incompatibility, framing point-in-time semantics, and V-Order/BinSize write-side levers

An Import-mode model has to be fully resident in memory in the service before it can answer a single query — there's no partial-load option for Import [S2]. Direct Lake is built around avoiding exactly that requirement: when a report visual asks for data, the model reads straight from the Delta table in OneLake and can keep recently touched data cached in memory to speed up the next query, but it never has to load the entire table up front [S5]. A Direct Lake on SQL table can drop into DirectQuery mid-query when native Direct Lake access isn't possible, and that fallback behavior is itself controlled by a configurable property on the model rather than happening unpredictably [S5].

The large-format storage engine has its own internal machinery worth understanding. Flipping the large-format toggle actually swaps the model's underlying service storage mechanism from an Analysis Services backup file (ABF) to Azure Premium Files, which is also why the feature only exists in regions where Premium Files is available [S4]. Large-format models default to an 8-million-row VertiPaq segment size — deliberately matched to Azure Analysis Services' own default, both to balance memory against query speed and to keep behavior predictable when migrating a model over from Azure Analysis Services [S4]. On top of that, the service applies dynamic memory management: it evicts semantic models that aren't currently active out of capacity memory so the combined footprint of everything hosted can exceed the SKU's own memory ceiling, though any single model is still bound by that SKU limit while it's loaded, and reloading an evicted model costs a noticeable query delay [S4]. On-demand load — on by default for large-format models — softens that eviction cost by paging in only the specific data pages a query actually touches instead of reloading the whole model from scratch [S4]. That paging behavior isn't a black box, either — querying the DISCOVER_STORAGE_TABLE_COLUMN_SEGMENTS DMV surfaces a Temperature score and a Last Accessed timestamp for every column, giving an administrator a concrete read on which parts of the model are hot right now versus sitting cold and unloaded [S4].

Diagnosing a model's real memory footprint uses the same DMV layer: summing DICTIONARY_SIZE from DISCOVER_STORAGE_TABLE_COLUMNS together with USED_SIZE from DISCOVER_STORAGE_TABLE_COLUMN_SEGMENTS, both queryable over the XMLA endpoint from SSMS, gives a working estimate of in-memory size [S4].

On the Copilot-DAX side, the internal mechanics that are actually grounded are narrower: the assistant reads Import-mode column data only as sampled min/max values rather than a full distribution scan when validating generated logic, which is a documented limitation on how deeply it can inspect the model rather than a description of a full query-execution path [S10]. Beyond that sampling behavior, no verified source in this knowledge base documents the underlying model-serving or retrieval architecture behind Power BI's Copilot features specifically.

Performance characteristics#

The one quantified risk documented for this workload is refresh-time memory exhaustion, not query latency: get a model's footprint up near half of what its hosting capacity can hold and a full refresh has a real chance of running the capacity out of memory before it completes [S4]. The prescribed fix is architectural rather than a knob to turn — restructure the refresh itself into narrower, partition-level calls instead of reloading everything at once [S4]. On the read side, the dynamic-eviction behavior described above is itself a performance characteristic worth planning around: an evicted model is fully functional but answers its next query slower while it reloads, and on-demand load exists specifically to blunt that penalty by paging in only what's needed rather than the entire model [S4].

Coming soon — this depth isn't in the knowledge base yet. It needs an L4/L5 source such as a Microsoft engineering blog or benchmark publishing measured VertiPaq query-latency numbers by segment size, Direct Lake cold-vs-hot query latency figures, or on-demand-load column-paging throughput numbers. Tracked in content/queue.md.

Worked example: choosing a mode for a growing sales model#

A BI team inherits a 6 GB sales semantic model in Import mode, refreshed nightly, that's starting to feel stale during the workday and is edging toward capacity memory limits during refresh. Working through the decision:

  1. Freshness first. The business wants same-day sales visibility, which rules out staying on nightly Import — that pushes toward DirectQuery or Direct Lake [S2].
  2. Data location. The sales fact table already lives as Delta in a Fabric lakehouse, so Direct Lake is viable without any data movement [S6].
  3. Flavor choice. No delegated-identity SQL endpoint requirement exists here, and the team wants the richer modeling surface, so Direct Lake on OneLake is the better default over Direct Lake on SQL [S7] [S6].
  4. Guard the join logic. The existing model joins Sales against a Customers view for segment enrichment — per the DirectQuery-fallback trap above, that join needs to be materialized into a Delta table first, not left as a SQL view, or the switch to Direct Lake buys nothing [S7].
  5. Composite fallback for dimensions. Small, slowly changing dimension tables (like a date table) can stay in Import inside the same composite model, since they don't benefit from Direct Lake's on-demand load the way the large fact table does [S7].
  6. Prep the model for Copilot while it's already being touched. Since the model is being reworked anyway, the team also runs it through Prep data for AI — renaming the handful of fields analysts actually ask about, adding a fiscal-year AI instruction, and marking the existing YoY-growth visual as a verified answer — rather than treating that as a separate future project [S11].

Inference: the specific sequencing of these six checks is this article's synthesis, not a single cited claim — each individual step is grounded, but the checklist itself is not something the sources present as a table.

The result is a Direct Lake on OneLake model with one materialized fact table and a small Import dimension, refreshing on a much shorter cycle without paying Import's full nightly reload cost, and pre-wired for Copilot to answer the sales questions the team already knows are coming.