Most Power Query users let default load settings create unnecessary worksheet tables and bloated workbooks. This lesson teaches you to deliberately control every output destination — connection-only staging layers, Data Model loading, and worksheet tables — so your pipelines are clean, fast, and production-ready.

You've built a solid Power Query pipeline — data comes in from three sources, gets cleaned, merged, and shaped exactly how you need it. Then a colleague opens the file and asks: "Why are there six extra tables in this workbook? And why is this one taking forever to refresh?" The answer almost always comes down to load destinations. Most Power Query users let the defaults do the work, and the defaults are not designed for production pipelines.
Understanding how to deliberately control where your query output lands — a worksheet table, the Data Model (Power Pivot), or nowhere at all (connection-only) — is the difference between a fragile proof-of-concept and a maintainable reporting solution. Get this right and you'll dramatically reduce file size, improve refresh performance, prevent users from accidentally editing intermediate data, and give yourself the architectural foundation to build genuinely scalable ETL workflows.
By the end of this lesson, you'll be able to architect a multi-query Power Query solution with full control over every output. You'll know when to use each load destination, how to switch between them, and how to avoid the gotchas that trip up even experienced practitioners.
What you'll learn:
You should be comfortable with the basics of connecting to data, applying transformations, and understanding the Power Query editor. If any of that is still fuzzy, Getting Started with Power Query: Master Connect, Transform, Load for Real-World Data is the right starting point. You should also have a working sense of how queries reference each other — if you haven't thought about that, Understanding Query Dependencies and Evaluation Order in Power Query: How the M Engine Executes Your Steps will fill in the gaps.
Before touching any settings, it's worth building a clear mental model. When Power Query finishes evaluating a query, that result — a table in memory — has to go somewhere. Power Query gives you three choices:
Load to worksheet table — The query result materializes as a formatted Excel Table on a worksheet. Users can see it, sort it, filter it, and (dangerously) accidentally edit it.
Load to Data Model — The query result is pushed into Power Pivot's in-memory columnar store (VertiPaq). It's compressed, invisible to casual users, and available for DAX measures and relationships.
Connection Only — The query is evaluated and held in memory only during refresh. Nothing is persisted to the workbook. It exists purely so other queries can reference it.
The confusion arises because Power Query has opinions. When you first import a query in Excel, the default is to load to a worksheet table. But if you add that query as a step in another query, Power Query may or may not materialize it — that depends on the evaluation engine, not on your explicit instruction. Understanding this distinction between explicit load destinations (what you configure) and implicit evaluation (what the engine does internally) is the foundation of everything that follows.
Key insight
A connection-only query still runs during refresh — it just doesn't write output to a persistent location. If it's expensive (hitting a slow API, reading millions of rows), it's still costing you time every refresh cycle. Connection-only controls where output goes, not whether the query executes.
Loading to a worksheet table is the most familiar destination. It's what most people think of as "the result" of a Power Query transformation. When you click Close & Load, that's where you end up by default.
Every row in a worksheet table is stored twice: once in the Power Query cache and once in the Excel grid. For a 100,000-row dataset, this adds up fast. It also means that every time the workbook calculates, Excel has to maintain those cells in memory.
More critically, worksheet tables are editable. A user who doesn't know the table is query-managed might delete rows, change values, or sort the data — and then the next refresh overwrites their changes. This creates support headaches that are entirely avoidable.
Warning
If you're loading to a worksheet table that others will view, protect the sheet or at minimum add a comment making clear the data is query-managed. You'd be surprised how often someone "cleans up" a query output table and then blames the query when their changes disappear.
In Excel's Queries & Connections pane (Data > Queries & Connections), right-click any query and choose Load To.... The dialog that appears gives you three radio buttons: Table, Only Create Connection, and Data Model. You can also access this from the Power Query Editor via Home > Close & Load To.
The key thing to understand here: changing a query's load destination doesn't change the query's M code at all. The transformations stay identical. You're only changing the output contract — where the engine delivers results after it finishes evaluating.
Connection-only is the most misunderstood load destination, and it's also the most powerful for building real ETL pipelines. When a query is connection-only, it participates in the query graph as a node that other queries can reference, but it doesn't write its output to the workbook.
Think of connection-only queries as the staging and intermediate layers of your pipeline. In data warehousing terms, they're your raw and cleansed layers that feed into your conformed or presentation layer.
Imagine you're building a monthly sales report in Excel. Your data comes from three sources:
A naive approach loads all three sources directly to worksheet tables and then builds a fourth query that merges them. The result: three unnecessary worksheet tables cluttering the workbook, three times the memory overhead, and three tables users can accidentally corrupt.
The right approach:
raw_transactions — Connects to SQL Server. Connection-only.raw_territories — Connects to SharePoint. Connection-only.raw_categories — Connects to the Excel file. Connection-only.clean_transactions — References raw_transactions, applies type corrections and null handling. Connection-only.dim_territory — References raw_territories, deduplicates and standardizes. Connection-only.fact_sales — Merges clean_transactions, dim_territory, and raw_categories. Loads to Data Model.Six queries, one output. Five of them are invisible to workbook users. The only thing that lands in the Data Model is the fully shaped, final result.
Tip
Name your connection-only queries with a prefix like raw_, stg_, or clean_ to make their role immediately obvious in the Queries & Connections pane. This is especially valuable when you hand the file off to someone else or come back to it six months later. See Power Query Best Practices for Maintainable ETL for a complete naming convention system.
In the Power Query Editor:
From the Queries & Connections pane without opening the editor:
The query's icon in the pane will update to show no worksheet or data model indicator — just a small connection symbol. When you refresh, the query runs but produces no visible output.
Because connection-only queries still execute during refresh, you need to think carefully about which ones are inherently expensive. If raw_transactions pulls 5 million rows from SQL Server, that query runs every time anything in its dependency chain refreshes. This is where query folding becomes critical — if your staging transformations fold back to the SQL engine, you're not dragging 5 million rows through the M engine unnecessarily.
The Data Model is Power Pivot's columnar in-memory store. When you load a query to the Data Model, it becomes a table available for DAX measures, relationships, and Power BI-style visualizations in Excel. This is where you want your final, authoritative, fully-shaped data to land.
The VertiPaq engine compresses columnar data extremely efficiently — often achieving 10:1 or better compression on typical business data. A dataset that takes 50MB as a worksheet table might take 5MB in the Data Model. For millions of rows, this difference is the margin between a usable file and one that crashes on open.
The Data Model also enables relationships between tables, which means you can load your fact table and your dimension tables separately and let DAX handle the joins at query time. This is fundamentally more powerful than pre-joining everything in Power Query — though there are scenarios where pre-joining in M is the right call.
In the Import Data dialog (Close & Load To or Load To from the pane):
Note the subtlety: the Data Model checkbox is separate from the destination radio button. You can:
Warning
Selecting both "Table" and "Add this data to the Data Model" stores your data twice — once in the Excel grid and once in VertiPaq. For large datasets this will bloat your file significantly and offers no benefit over picking one destination. Choose one.
| Scenario | Recommendation |
|---|---|
| Data feeds Excel formulas (VLOOKUP, XLOOKUP) | Worksheet table |
| Data feeds PivotTables with DAX measures | Data Model |
| Data feeds Power BI after publishing | Data Model |
| Dataset is under 50K rows, no DAX needed | Worksheet table |
| Dataset is 100K+ rows | Data Model |
| Multiple tables need relationships | Data Model |
| Output must be visible/auditable by users | Worksheet table |
Load destination is one half of the control story. The other half is refresh behavior — specifically, which queries refresh when, and whether they can be refreshed independently.
In Excel, you can right-click any individual query in the Queries & Connections pane and choose Refresh to refresh only that query. This is useful during development when you want to test one stage without triggering expensive upstream queries.
However, this can create inconsistency in production: if you refresh fact_sales without refreshing raw_transactions, your output reflects stale source data. For automated scenarios (where refresh is triggered by a scheduled task or VBA), you typically want to refresh all queries at once via Data > Refresh All.
Key insight
"Refresh All" in Excel refreshes every connection in the workbook — including any pivot tables connected to external OLAP cubes, OData connections, and legacy external data ranges, not just Power Query connections. If your workbook has legacy connections you didn't create, this can cause unexpected behavior or errors.
Power BI Desktop doesn't have the same selective refresh capability at the query level that Excel does. All queries refresh together when you trigger a refresh, either manually or when the report is published to the Power BI service and a scheduled refresh runs.
This makes connection-only query architecture even more important in Power BI — because you can't easily skip expensive staging queries, they need to be fast. This is where parameterized queries and incremental refresh patterns become essential for managing large datasets.
There's a subtle but important distinction in Power BI Desktop that doesn't exist the same way in Excel: "Enable load" is a toggle on each query. When you uncheck Enable Load on a query in Power BI, it becomes the equivalent of connection-only — it can be referenced by other queries but doesn't produce a table in the report.
To toggle this in Power BI Desktop:
The query name will appear italicized in the panel, indicating it's not loading to the model. This is how you build staging and intermediate transformation layers in Power BI — identical in concept to connection-only in Excel, different in terminology.
Let's build this properly. You're creating a regional sales performance dashboard in Excel. Data comes from:
The goal: one Data Model table — fact_sales_enriched — that joins transactions with rep names and product hierarchy, with no intermediate worksheet tables cluttering the workbook.
raw_csv_sales — Uses folder combination to stack all CSV files. Connection-only.
This query uses the standard folder combine pattern. After combining, you have all transactions with a Source.Name column identifying the file origin. No transformations yet.
raw_hr_reps — Connects to the HR Excel workbook's named range. Connection-only.
dim_product_hierarchy — A hardcoded or M-generated lookup table. Connection-only.
clean_sales — References raw_csv_sales. Applies type conversions, removes nulls in key columns, standardizes region codes.
let
Source = raw_csv_sales,
TypedColumns = Table.TransformColumnTypes(Source, {
{"TransactionDate", type date},
{"Amount", type number},
{"RegionCode", type text},
{"ProductID", type text},
{"RepID", type text}
}),
RemoveNullAmounts = Table.SelectRows(TypedColumns,
each [Amount] <> null and [Amount] > 0),
StandardizeRegion = Table.TransformColumns(RemoveNullAmounts, {
{"RegionCode", Text.Upper, type text}
})
in
StandardizeRegion
Set this as connection-only.
clean_reps — References raw_hr_reps. Selects only the columns you need (RepID, FullName, Region), deduplicates on RepID.
let
Source = raw_hr_reps,
SelectColumns = Table.SelectColumns(Source, {"RepID", "FullName", "Region"}),
Deduplicated = Table.Distinct(SelectColumns, {"RepID"})
in
Deduplicated
Set this as connection-only.
fact_sales_enriched — Merges everything together. This is the only query that loads to the Data Model.
let
Source = clean_sales,
// Join rep names
MergeReps = Table.NestedJoin(
Source, {"RepID"},
clean_reps, {"RepID"},
"RepData", JoinKind.LeftOuter
),
ExpandReps = Table.ExpandTableColumn(
MergeReps, "RepData",
{"FullName", "Region"},
{"RepFullName", "RepRegion"}
),
// Join product hierarchy
MergeProducts = Table.NestedJoin(
ExpandReps, {"ProductID"},
dim_product_hierarchy, {"ProductID"},
"ProductData", JoinKind.LeftOuter
),
ExpandProducts = Table.ExpandTableColumn(
MergeProducts, "ProductData",
{"ProductName", "Category", "Subcategory"},
{"ProductName", "Category", "Subcategory"}
),
// Final column selection and ordering
FinalColumns = Table.SelectColumns(ExpandProducts, {
"TransactionDate", "RepID", "RepFullName", "RepRegion",
"ProductID", "ProductName", "Category", "Subcategory",
"Amount", "RegionCode"
})
in
FinalColumns
When you close and load this query, choose Only Create Connection and check Add this data to the Data Model.
Tip
When building merge-heavy final queries like fact_sales_enriched, pay attention to row counts after each join. If your LeftOuter join is producing more rows than your source table, you have a many-to-many relationship issue in your dimension data. Check for duplicate keys in clean_reps and dim_product_hierarchy before assuming the merge logic is wrong. Managing many-to-many relationships covers the diagnostic approach in detail.
Your Queries & Connections pane shows six queries:
raw_csv_sales — connection onlyraw_hr_reps — connection onlydim_product_hierarchy — connection onlyclean_sales — connection onlyclean_reps — connection onlyfact_sales_enriched — loads to Data ModelThe workbook has zero query-generated worksheet tables. Users see only the pivot tables and charts you've built on top of the Data Model. The architecture is clean, documented by naming convention, and trivially easy to extend.
Power Query's engine determines evaluation order based on the dependency graph — if fact_sales_enriched references clean_sales and clean_reps, those will always be evaluated first. You don't need to manually control evaluation order within a dependency chain.
What does require attention is when you have multiple independent chains that need to coordinate. For example, if you have both a fact_sales_enriched table and a separate dim_date table both loading to the Data Model, they're evaluated independently — potentially in parallel. This is usually fine, but can cause issues if both chains reference a common volatile source (like an API that rate-limits requests).
Orchestrating multi-query refresh dependencies goes deep on strategies for managing this in complex pipelines. For most single-workbook scenarios, the dependency graph handles ordering automatically and correctly.
Note
In Power BI Desktop, all enabled queries refresh in parallel by default. This is great for performance but means you can't assume one query finishes before another independent query starts. If two queries need to read from the same slowly-changing source, they may get different snapshots of the data. For transactional consistency, consider staging all source data through a single connection-only "snapshot" query that everything else references.
Build the following pipeline from scratch in a new Excel workbook. Use data you create manually or adapt from your own work environment.
Scenario: You have three small tables of order data:
Create three Excel tables in a new workbook:
Populate each with at least 10 realistic rows.
Your tasks:
Connect to all three tables using Power Query. Set all three queries as connection-only. Name them raw_orders, raw_customers, raw_products.
Create a clean_orders query that references raw_orders, adds a calculated TotalAmount column (Quantity × UnitPrice), and filters out any rows where Quantity is zero or null. Set as connection-only.
Create a fact_orders_enriched query that merges clean_orders with raw_customers (on CustomerID) and raw_products (on ProductID). Expand only the columns you need from each dimension. Set this query to load to the Data Model only (connection-only + Add to Data Model).
Build a PivotTable in Excel that uses the Data Model — you should see fact_orders_enriched as a table to pivot against.
Open the Queries & Connections pane and verify: you should see five queries, four of them connection-only, and the workbook should have zero query-generated worksheet tables visible.
Stretch goal: Add a sixth query, audit_order_count, that loads to a worksheet table and contains a single row with two columns: RefreshTimestamp and OrderCount. Use DateTime.LocalNow() for the timestamp and Table.RowCount(fact_orders_enriched) for the count. This gives you an audit table that's intentionally surfaced while keeping the main data in the model.
This is the number one confusion. Connection-only queries produce no visible output — that's the point. If you're expecting to see data somewhere and don't, check whether your final output query (the one that should load to a table or model) is actually configured correctly. Right-click it in the Queries & Connections pane and verify its load destination.
You have a query somewhere that's still set to load to a worksheet table when you intended it to be connection-only. Check every query in the pane — queries with a worksheet icon next to them are loading to the grid. Also check for any legacy external data connections from before the Power Query era.
The relationship between your Data Model table and any dimension tables needs to exist before DAX aggregations work correctly. If you're loading a single wide table (fact_orders_enriched in the exercise above) with all dimensions already joined in, you don't need relationships — all columns are in the same table. But if you're loading a normalized fact+dimensions structure, you need to define those relationships in the Power Pivot Data Model view.
Changing a query's load destination never affects the M code or the query's availability as a reference for other queries. Connection-only queries are fully referenceable. What can break downstream queries is if you accidentally delete a query while trying to change its destination, or if you rename it. Always use the right-click Load To approach, not delete-and-recreate.
This usually means you've accidentally checked both "Table" (worksheet) and "Add this data to the Data Model," storing the data twice. Open the Queries & Connections pane, right-click the culprit query, choose Load To, and uncheck whichever destination you don't need. Then save and confirm the file size drops.
Warning
Switching a query from "Load to Table" to "Connection Only" will delete the worksheet table associated with that query — including any manual formatting or formulas referencing cells in that table. If you have downstream formulas depending on a query-managed table, plan the migration carefully. Document what's referencing that table before making the switch.
In Power BI Desktop, the equivalent is unchecking Enable Load on the query. Right-click the query in the Queries panel and look for that toggle. Queries with Enable Load unchecked appear in italics in the panel and don't produce tables in the report model — identical behavior to connection-only in Excel, just different UI terminology.
The ability to control load destinations precisely is what separates an ad-hoc Power Query user from someone who builds production-grade reporting pipelines. Here's the core of what you've learned:
For your next steps, consider how this architecture interacts with more advanced topics:
Parameterized queries let you make your raw source queries dynamic — passing date ranges or filter values that change what data flows through the entire pipeline. Parameterized Queries and Dynamic Data Sources in Power Query walks through this end to end.
Multi-stage staging architectures take the pattern you've built here further, creating explicitly separated raw, cleansed, and conformed layers with well-defined contracts between them. Building Multi-Stage Staging Architectures in Power Query is the natural next lesson.
Scheduling and managing refresh failures becomes critical once your pipeline runs automatically in the Power BI Service. Scheduling and Managing Power Query Refresh Failures in Power BI Service covers diagnostics and recovery workflows.
The architecture decisions you make around load destinations echo through every layer of your reporting solution. Build them deliberately from the start, and you'll save yourself weeks of refactoring later.