← All articles
Direct LakeFabric

Direct Lake vs. Import Mode: What Actually Changes

Direct Lake sounds like a free lunch: Import-mode-speed queries directly against Delta tables in OneLake, with no scheduled refresh. In practice, it changes the rules of the game rather than just removing a step — and if you design a model the way you would for Import mode, you'll hit the fallback path without realizing it.

What Direct Lake actually does

Instead of loading data into an in-memory VertiPaq cache on a schedule, Direct Lake reads Parquet files straight from OneLake and builds column segments in memory on demand, at query time. When those segments are already resident, you get Import-mode-like performance. When they're not, or when the engine decides it can't serve a query from the lake directly, it falls back to DirectQuery — silently, and with a very different performance profile.

The fallback triggers that catch people out

  • Row-level security with complex DAX in the RLS filter can force a fallback for the tables involved.
  • Calculated columns and calculated tables aren't supported in Direct Lake and will push the whole table to DirectQuery.
  • Schema drift between the OneLake table and the semantic model (a column renamed or dropped upstream) breaks the mapping.

A measure that helps you see it happening

Fallback Check =
VAR EngineUsed =
    SELECTEDVALUE ( 'Diagnostics'[StorageEngine] )
RETURN
    IF (
        EngineUsed = "DirectQuery",
        "⚠ Fell back",
        "✓ Direct Lake"
    )

This isn't something you can query from a measure in production — you'd pull it from the query plan or Log Analytics — but it's a useful mental model: treat every Direct Lake table as "Direct Lake until proven otherwise," and check the fallback conditions the same way you'd check a query plan for a table scan.

Where this leaves your design

Keep transformations upstream, in the lakehouse, not in calculated columns. Keep RLS filters simple — a single-column equality against a security table beats a computed expression every time. And treat schema changes upstream as breaking changes to your semantic model, because that's exactly what they are.