Optimize enterprise-scale semantic models
Objective coverage
- Implement performance improvements in queries and report visuals
- Improve DAX performance
- Configure Direct Lake, including default fallback and refresh behavior
- Choose between Direct Lake on OneLake and Direct Lake on SQL analytics endpoint
- Implement incremental refresh for semantic models
Optimize an observed bottleneck
Optimization starts with an observed user action, a reproducible query, and a correct expected result. “The report is slow” is a useful symptom but not a diagnosis. The delay may be visual rendering, DAX evaluation, source queries, data loading, capacity contention, or a dependency outside the model. Changing several settings at once can improve one timing while hiding the actual cause. Establish a baseline, change one hypothesis at a time, and retain a correctness fixture throughout.
Northstar's executive report has a monthly revenue matrix, a product ranking, and a delivery-status chart. It runs quickly for one author but slowly for consumers during the morning refresh window. The team will separate query shape, identity, cold versus warm cache behavior, and concurrent capacity use. All timing figures in this chapter are invented examples of interpretation, not benchmark claims for a Fabric capacity.
Implement performance improvements in queries and report visuals
A report interaction can trigger multiple visual queries and rendering work. Performance Analyzer helps inspect supported report timing components and obtain query information. A slow page can contain one expensive query, too many individually reasonable visuals, or rendering overhead unrelated to data retrieval. Model design and source performance also affect those queries. Measure the actual interaction under the intended identity and filters; a fast author session with warm caches may not represent a consumer opening the report for the first time.
Choose one repeatable interaction, such as opening a page or changing Region. Record filters, identity, data version, and concurrency. Capture visual timings and identify the dominant component. Reduce unnecessary visuals or high-cardinality detail when that preserves the business requirement. Inspect the generated DAX and the model relationships before rewriting measures. For DirectQuery, investigate the translated source workload and source response. Repeat the same interaction after the change, compare correct results, and test a cold or less favorable condition as well as the warm case.
A page has 12 visuals. One detailed matrix accounts for most query time, while several decorative visuals add modest rendering work. The team limits the matrix to the requested summary grain and provides drillthrough for detail. The new page returns the same regional totals and improves the observed interaction. If they instead removed the Region filter to make the query faster, the result would no longer satisfy the requirement. Performance acceptance includes response time and semantic equivalence; a faster wrong answer is a regression.
Timing categories require interpretation. A long total duration may include waiting behind other work rather than an intrinsically slow expression. Repeated runs can become faster because caches warmed. Compare comparable conditions and record variation instead of reporting one best sample. Security filters can change query shape, so test consumer roles. In exam scenarios, Performance Analyzer is a useful entry point for report-level diagnosis, while capacity metrics and source query tools address different layers. Choose the tool that can observe the suspected bottleneck.
Scenario: A report is slow only when a detailed matrix is expanded to thousands of products. What should be investigated before buying more capacity?
Answer: Capture that visual's query and rendering timings, inspect its required grain and cardinality, and evaluate a summary-plus-drillthrough design. Check the measure and source workload under the same filters. Confirm that the revised view preserves the analytical task before attributing the issue solely to capacity.
Recall: Why should cold and warm interactions be measured separately? What evidence distinguishes visual rendering delay from a slow data query?
Improve DAX performance
DAX performance depends on model structure, cardinality, filter propagation, storage mode, and the expression. Efficient formulas often make the intended filter scope explicit and avoid unnecessary iteration or repeated work. Variables can improve readability and reuse intermediate values, but they are not a universal speed guarantee. A Boolean filter on a column can be preferable to scanning a whole table when both express the same requirement. More complex conditions may genuinely require FILTER or an iterator. Preserve semantics before simplifying syntax.
Capture the expensive query and isolate the measures contributing to it. Establish expected results for leaf rows, totals, and important slicer combinations. Inspect repeated expressions, broad table filters, high-cardinality iterators, and unnecessary filter removal. Simplify one expression at a time and compare execution using supported tooling. Keep an eye on the model: a missing relationship or overly detailed table can force expensive formula work. Retest under representative security and storage conditions, including an empty result and a high-cardinality selection.
Suppose the requirement is revenue for blue products while respecting existing selections. A column predicate with KEEPFILTERS can express the intersection directly:
Blue Revenue =
CALCULATE (
[Revenue],
KEEPFILTERS ( Product[Color] = "Blue" )
)
This is a different question from forcibly replacing every selected color with Blue. A FILTER over the complete Sales table may be unnecessary for this simple dimension predicate and can obscure the intended scope. However, a rule selecting months whose calculated profit exceeds a threshold may need a table expression evaluated at month grain. The optimization is to choose the smallest correct operation, not to ban a function by name.
Moving an expression into a variable can change evaluation timing, especially around CALCULATE and iterators. Removing FILTER can change a measure-dependent condition into an invalid or semantically different predicate. Replacing blanks with zero can expand visible combinations and increase work. If a rewrite is faster, compare all relevant results rather than a single total. For exam distinctions, prefer selective column filters and clear reusable measures when they fit, but retain necessary context-sensitive logic. Measure performance on the actual model rather than inferring it solely from formula length.
Scenario: A rewritten measure is faster but now returns Blue revenue even when the report explicitly filters Color to Red. What semantic change should be checked?
Answer: Check whether a filter argument replaced the existing Color filter instead of intersecting it. If the requirement is to respect the user's selection, use the appropriate intersection behavior and validate the Red-only case. Performance gains do not justify silently changing the measure's population.
Recall: Why is filtering a dimension column often clearer than filtering the entire fact table? When does a measure-based condition still require a table expression?
Configure Direct Lake, including default fallback and refresh behavior
Direct Lake uses the semantic engine to query supported Delta data in OneLake. Its refresh or framing operation updates the model's view of table metadata and the relevant data files; it is not the same full data-copy operation as an Import refresh. Columns needed by queries can be loaded into memory as required. Direct Lake on SQL analytics endpoints has supported DirectQuery fallback behavior controlled by the model's Direct Lake behavior setting. Direct Lake on OneLake does not use that SQL fallback path. Always identify the variant before diagnosing a query.
Verify the model variant, supported source tables, connection identity, permissions, and capacity requirements. Inspect automatic-update and refresh behavior for the model. Add a known test row upstream, confirm it is committed and available in the Delta table, then validate the model's framing and query result. For the SQL endpoint variant, inspect the configured Direct Lake behavior and conditions that cause fallback, such as certain SQL view or granular-security scenarios. Use supported diagnostics to identify the execution mode rather than inferring it from a report's appearance.
Northstar's SQL-endpoint Direct Lake model uses a SQL view for a derived projection. A query can use DirectQuery fallback rather than loading a physical Delta table directly. Its slower timing may therefore reflect the SQL query path. Moving the required transformation upstream into a supported physical Delta table can change the execution path, but the team must preserve the projection's semantics and security. If the model is configured to disallow fallback, an unsupported Direct Lake query can fail instead of silently taking DirectQuery. That failure is diagnostic information, not evidence that the source data vanished.
Do not call all slow Direct Lake queries fallback. Cold column loading, memory pressure, table layout, capacity contention, and expensive DAX can also explain latency. Conversely, a refresh that completes quickly does not prove the upstream tables contain current data. Observe each boundary. Guardrails and feature restrictions vary with capacity and product evolution, so use current documentation for exact limits. The exam distinction is between upstream data preparation, model framing, in-memory query work, and the SQL variant's possible fallback path.
Scenario: A SQL-endpoint Direct Lake model becomes slow after a table is replaced by a SQL view. Which execution behavior should be checked?
Answer: Check whether queries now fall back to DirectQuery and inspect the resulting SQL path. Confirm the model's Direct Lake behavior setting and whether a supported physical Delta representation could satisfy the same business logic. Preserve security and compare results before changing the source design.
Recall: How does framing differ from Import refresh? Why can DirectLakeOnly expose a condition that Automatic might handle through fallback?
Choose between Direct Lake on OneLake and Direct Lake on SQL analytics endpoint
The two Direct Lake variants differ in discovery, supported composition, source scope, and security integration. Direct Lake on OneLake accesses supported Delta tables directly and can draw from multiple supported Fabric sources; it has no DirectQuery fallback through a SQL analytics endpoint. Direct Lake on SQL analytics endpoints discovers through a single supported source endpoint and can fall back under documented conditions. SQL endpoint policies do not automatically become OneLake file-access policies. The choice must satisfy both modeling and security requirements.
Inventory the required source items and model features, including any Import additions or SQL views. Map the intended query identity and the authorization layer for each source. Compare the currently supported capabilities of both variants. Prototype the specific security personas and unsupported-query cases that matter to the design. Verify whether the model relies on source SQL RLS, semantic-model RLS, OneLake security, or a combination supported by the selected path. Document failure behavior when a query cannot be served, and avoid assuming fallback exists in both variants.
Northstar needs curated Delta tables from two Fabric items plus a small imported planning table. Direct Lake on OneLake is a candidate because its supported composition differs from the SQL-endpoint variant. The team checks current authoring support and configures the intended source identity and model security. A different solution depends on SQL views and endpoint-enforced granular policies; that requirement needs analysis of the SQL endpoint variant and its fallback implications. Choosing the newer-sounding name without examining those requirements would be poor design.
A fixed connection identity and single sign-on have different implications. With a fixed identity, source access is evaluated for that identity while semantic-model controls govern consumers as configured; with SSO, the consumer identity participates in source authorization. Neither choice makes excessive source grants harmless. Read the current security integration guidance and test negative cases. For exam distinctions, separate Direct Lake on OneLake's lack of SQL fallback from Direct Lake on SQL's configurable fallback behavior. Also separate supported table composition from security enforcement.
Scenario: A team moves from SQL-endpoint Direct Lake to Direct Lake on OneLake and assumes its SQL endpoint row policies still govern every read. What must be reviewed?
Answer: Review the new data-access path, source identity, OneLake permissions, and semantic-model security. SQL endpoint rules are not a universal policy on direct file access. Test allowed and denied consumers under the chosen supported security design, and do not expect SQL DirectQuery fallback in the OneLake variant.
Recall: Which variant can use SQL endpoint fallback? Why should source identity be part of the architecture decision rather than an afterthought?
Implement incremental refresh for semantic models
Incremental refresh limits repeated processing of eligible imported data by managing date-based partitions according to a policy. The historical storage window defines how much history remains; the refresh window defines which recent periods are processed again. RangeStart and RangeEnd are case-sensitive Date/Time parameters used in the table's filtering expression. The service applies the policy after publication and refresh. A small Desktop sample is therefore not the final service partition layout. Late corrections outside the refresh window require an explicit strategy.
Choose a suitable date column and define the business meaning of retention and refresh windows. Create RangeStart and RangeEnd with Date/Time types. Apply a nonoverlapping filter, commonly Date >= RangeStart and Date < RangeEnd. Verify query folding or otherwise confirm efficient source-side filtering for the connector. Configure the policy, publish to a supported environment, and run the initial refresh. Inspect subsequent refresh behavior and validate boundary rows, historical retention, and a late update. Plan how authorized operators will repair periods outside the routine window.
Northstar retains five years of sales and refreshes the most recent ten days because corrections normally arrive within a week. The initial refresh must load the retained history and can be much more expensive than later runs. A row exactly at midnight on July 1 belongs in the July interval and not in the interval ending at July 1 when half-open boundaries are used. A correction dated three months ago will not necessarily be picked up by the ten-day policy. The team needs a targeted historical refresh or another approved repair process for that exception.
A policy checkbox does not prove folding or correct partition boundaries. If both ends use inclusive equality, boundary rows can appear in adjacent partitions. If a transformation prevents efficient source filtering, each partition refresh may scan far more data than expected. Detect data changes has its own semantics and does not magically detect every deletion or arbitrary historical correction. A hybrid real-time partition is a separate supported option with licensing and query implications. Incremental refresh for Import models is different from Direct Lake framing and from an upstream pipeline's incremental copy.
Scenario: A model retains five years and refreshes ten days, but an accountant changes a transaction from three months ago. Why is the report unchanged after the normal refresh?
Answer: The changed transaction is outside the routine refresh window. Confirm the source correction, identify the affected historical partition, and use an authorized supported repair refresh or adjust the policy according to business requirements. Do not assume the existence of a retention window means every retained period is reprocessed each time.
Recall: Why should only one partition boundary include equality? What evidence shows that the source is filtering efficiently rather than returning the full table for each partition?
Direct Lake decision walkthrough
Start with the data path, not the model's display name. Write one line identifying the producing item, the Delta table or SQL view, the Direct Lake variant, the connection identity, and the consumer. Then describe how new data becomes visible. The producer may need an ingestion or transformation job; the model may need framing or an automatic update; the report still needs to issue a query. If any stage is stale or unauthorized, the final visual can be wrong or unavailable even while another stage reports success.
For a SQL-endpoint variant, test a simple physical Delta table first. Record the observed query behavior and result. Introduce a supported view-based case only if the requirements need it, and inspect whether the execution path changes. If a fallback occurs, measure the SQL workload rather than attributing every delay to Direct Lake column loading. If fallback is disallowed, record the error and its cause. This controlled comparison distinguishes an architectural limitation from a capacity problem.
For a OneLake variant, test the same business result through its supported direct access path, with the appropriate identity and security controls. Do not expect the engine to recover by sending the query through the SQL analytics endpoint. A model that spans multiple sources also needs a consistency contract: two tables may have been prepared at different times. A quick framing operation does not turn those independently updated sources into a single business transaction. Align upstream publication or communicate the resulting data-version boundary.
Security tests should include a consumer with the intended model access and a consumer who must be denied. If SSO is used, verify the source permissions for those users. If a fixed identity is used, verify its source scope and the model's consumer restrictions. Inspect direct data access separately where consumers have it. A report RLS test cannot establish the safety of an unrelated notebook path. This distinction connects optimization to governance: changing execution paths can change which security mechanisms participate.
Incremental refresh laboratory on paper
Construct six source records with dates immediately before, exactly at, and immediately after a monthly boundary, plus one corrected historical record, one deleted record, and one recent record. Specify the source's version and deletion behavior. Write the rows that should belong to each partition under Date >= RangeStart and Date < RangeEnd. Every retained row should belong to exactly one partition. If a row belongs to two, the boundary conditions are wrong; if it belongs to none, inspect gaps and time-zone conversion.
Now simulate the initial service refresh. It must create and populate the retained history according to the policy, not merely load the small Desktop parameter sample. Record the expected count and sum for each period. Simulate a later refresh that processes only the recent window. The old correction should remain unchanged unless the design deliberately refreshes that historical period. This is not a bug in the partition concept; it is a mismatch between the correction horizon and the chosen operational policy.
Deletion handling deserves a separate test. A change-detection column based on a maximum timestamp cannot be assumed to identify every deleted historical row. Ask whether the source provides soft deletes, a change feed, or another signal and whether the semantic refresh policy actually revisits the relevant partition. A correct upstream current-state table can coexist with a stale imported historical partition. Reconcile the model at a granularity that can expose the difference rather than checking only the latest day's total.
Finally, inspect query folding or the actual source requests. The desired behavior is for each refresh partition to request the relevant bounded data efficiently. A filter that appears late in a nonfolding transformation can force broad reads before local filtering. A small preview can conceal this cost. Use the connector's supported diagnostics and source observation to verify the execution path. If native query or transformation limitations prevent efficient folding, redesign the preparation boundary rather than assuming the policy itself guarantees source efficiency.
Measure an improvement without changing the question
Suppose a baseline interaction takes 4.2, 4.5, and 4.3 seconds under comparable warm conditions. A revised measure takes 2.8, 2.9, and 2.7 seconds with identical filters and results. This is useful evidence for that interaction and environment. It is not proof that every report is faster or that cold loading, security roles, and concurrency are unaffected. Add those cases when they are material to the user experience, and retain the original baseline definition so the comparison can be repeated.
If the change also reduces the displayed date range from five years to one month, the timings no longer isolate the formula improvement. The workload became smaller. That may still be a valid product decision, but it must be described accurately. Similarly, increasing capacity while changing DAX and table layout makes attribution difficult. A measured improvement should say what changed, what was held constant, and what result was preserved. These habits make performance work more credible than a single impressive screenshot.
A practical acceptance record includes the model version, data version, identity, filters, visual interaction, observed timings, expected numerical result, and known limitations. For a DirectQuery or fallback path, include relevant source behavior. For Direct Lake, include cold and warm conditions and the variant. For Import, include refresh freshness and any partition change. Stop tuning when the agreed user outcome is met and further changes would add complexity without demonstrated value.
Shared Fabric foundations
The optimization experiment contract
Optimize the dominant bottleneck. If time is source I/O, adding pipeline activities can hurt. If one Spark partition is skewed, adding executors leaves one long task. If capacity throttles many workloads, a local SQL rewrite may not explain all latency. Scaling is valid when measured demand genuinely exceeds available resources after reasonable efficiency work, but it proves only that more resources helped that tested workload.
Warehouse optimization field guide
Statistics help estimates; stale or absent statistics can lead to a poor join
order or movement. Materialized views or persisted curated tables can trade
refresh/storage cost for repeated query savings. Avoid wrapping a filter column
in a conversion when the same boundary can be expressed on the original type.
Avoid SELECT *, accidental Cartesian joins, and row-by-row procedural logic.
Capacity scale can help concurrency saturation but not a query that scans every
wide row unnecessarily.
Lab. Start with a query joining order facts to a dimension whose business key is duplicated. Capture the wrong row count and plan. Repair dimension uniqueness, project only required columns, add a selective date predicate, and compare scan, duration, and correct total. Next preaggregate facts before a consumer-level join and compare. Run at one and several concurrent users so a single-query gain is not mistaken for workload capacity.
For regressions, compare code/data/statistics/plan/concurrency/capacity changes. If all queries slow, suspect shared resource or blocking before rewriting each. If only one parameter shape slows, investigate selectivity and plan behavior. Do not “optimize” by removing correctness filters or changing decimal semantics.
Optimization scenario drills
Fast query, expensive capacity
A warehouse rewrite lowers median latency from 12 to 4 seconds but doubles CU consumption and worsens p95 under concurrency. The change is not automatically an improvement. Recheck result equivalence, scan/data movement, plan, repeated work, and concurrency. Decide against the stated SLA and cost objective: perhaps 8 seconds at lower CU meets the business need and protects other workloads.
Report latency distribution and cost together. A local speedup that causes capacity throttling can make the overall product slower. Optimization ownership extends beyond the single developer's test query.
Small files caused by streaming writes
A Delta table receives frequent tiny micro-batches and accumulates thousands of
small files per day. Queries spend substantial time listing/planning and launch
many tiny tasks. Measure file distribution and scan/task evidence, then choose a
maintenance cadence or optimized-write strategy that compacts after sufficient
accumulation without running OPTIMIZE after every batch.
Coordinate compaction, V-Order, readers, retention, and vacuum safety. Compare end-to-end write plus maintenance cost with query benefit. If queries do not read the table often, aggressive maintenance may cost more than it saves.
Parallelism cliff
A Copy pipeline improves from concurrency 1 to 4, then slows at 16 while source throttling and sink commit waits rise. Select the measured knee—perhaps 4 or 8— and use backoff. Tune copy-internal parallelism and ForEach concurrency together because their product determines pressure. Repartition source work so one giant partition does not dominate.
Repeat across representative volume and time, since external source limits can vary. Validate target counts and file layout; faster transfer that produces a small-file problem moves the cost downstream.
Broadcast assumption fails
A lookup table was small during development but grows to several gigabytes. Forced broadcast now causes executor memory pressure and failures. Remove the assumption or define a guarded size threshold, inspect the adaptive/actual plan, and choose a partitioned join strategy. Project only required lookup columns and filter it before considering broadcast.
Compare shuffle, spill, task distribution, executor memory, duration, and correct totals. “Dimension” is a logical role, not proof that its physical size is safe to copy to every executor.
Materialization freshness trade-off
A KQL aggregation over raw events is run hundreds of times per hour. A materialized view can shift repeated query computation to ingestion/maintenance, but adds storage, update cost, and freshness/late-data semantics. Measure total query savings against ingestion overhead and verify supported functions and correction behavior.
If users require immediate raw detail and only a few queries use the aggregate, direct query may be better. If the aggregate is stable and dominant, materialize with monitoring for health and lag. Cost is moved and amortized, not magically removed.
Scaling after efficiency work
Capacity Metrics shows sustained throttling across well-designed concurrent workloads after unnecessary scans, skew, retries, and schedules are addressed. Scaling or autoscale is now an evidence-backed option. Define expected demand, budget, success metric, and rollback; compare throttling, latency, throughput, and CU/cost after the change.
Scaling is not a failure of engineering when demand exceeds the provisioned resource. It is a poor first answer when one accidental Cartesian join or unbounded stream state consumes the capacity.
Capstone: optimize without moving the bottleneck
A Fabric product misses its 07:00 freshness objective. Pipeline elapsed time is 95 minutes, Spark transformation 40 minutes, warehouse publish 20 minutes, and semantic refresh 25 minutes, but several stages overlap. Interactive reports also slow during the load. The team proposes a larger capacity immediately.
Establish the critical path
Create a timeline using trigger, queue, source extraction, Copy, Spark stages, warehouse application, model refresh, and publish. Overlap means durations cannot simply be added. Identify the earliest time each required output is ready and the dependency that determines consumer readiness. Collect Capacity Metrics for throttling and workload overlap, item run IDs, source/sink throughput, Spark UI, warehouse query/plan, and refresh partition detail.
Set fixed correctness controls: selected source rows = accepted + rejected, target distinct business keys, amount totals, late partition count, and consumer-visible maximum business time. Record three comparable baseline days and their cache/concurrency/capacity state.
Competing hypotheses
Pipeline evidence shows 6,000 tiny files and source throttling at high copy parallelism. Spark shows large file-list/task overhead plus one skewed customer key. Warehouse publication scans the full fact table despite processing one day. Semantic refresh unnecessarily processes historical partitions. Capacity also shows brief throttling while all operations overlap.
These are four hypotheses, not one “Fabric is slow” diagnosis. Test in controlled increments:
- Reduce Copy/ForEach concurrency to the measured throughput knee and consolidate file boundaries, preserving restartable partitions.
- Compact/optimize accumulated Delta layout at an evidence-based cadence and address Spark skew through preaggregation or a targeted strategy.
- Make warehouse application and query predicates prune the bounded date range; update relevant statistics and inspect the changed plan.
- Configure/validate semantic incremental partitions and schedule heavy stages to reduce unnecessary contention where business dependencies permit.
Do not apply every change at once. Each experiment retains input version, configuration, p50/p95 or repeated duration, bytes/files/tasks/shuffle/scan, capacity/CU, and correctness checksum.
Interpret results
Suppose file consolidation cuts Spark planning/task overhead by 12 minutes; skew repair removes a 9-minute tail; bounded warehouse processing saves 8 minutes; incremental semantic refresh saves 10. Scheduling reduces p95 report latency during the load. End-to-end readiness improves by only 25 minutes because some savings overlap. Report critical-path improvement, not the sum of local speedups.
Capacity now shows no throttling on typical days but p95 seasonal days still breach SLA. Model seasonal demand and compare further efficiency, schedule, autoscale, or SKU change. Scaling is now evaluated against a residual measured resource limit rather than masking small files, skew, full scans, and unnecessary refresh.
Regression and operations
Add thresholds for file-count/size distribution, Spark skew ratio and spill, pipeline throughput/throttling, warehouse scan/plan regression, refresh duration, capacity throttling, and end-to-end freshness. Avoid alerting on one noisy sample; use appropriate windows and recovery. Maintenance jobs themselves consume capacity, so schedule and measure compaction/materialization costs.
The capstone passes when the same source produces identical accepted/rejected counts and business totals; the critical path meets the objective on repeated representative runs; p95 interactive performance does not regress; capacity cost is reported; every maintenance/scale decision has ownership and rollback; and a future data-volume change can be detected before the original bottleneck returns.
Sources and provenance
The measured objectives follow the DP-600 blueprint effective July 21, 2026. Product references were retrieved for this edition; the book manifest records the actual retrieval time and SHA-256 of each downloaded HTML response. Examples and scenarios are original teaching material. Shared field guides reuse this project’s original DP-700 writing where the underlying Fabric concepts apply. Microsoft Learn remains authoritative, especially for current feature support and capacity limits.
- Study guide for Exam DP-600: Implementing Analytics Solutions Using Microsoft Fabric
- Use Performance Analyzer to Examine Report Performance - Power BI
- Avoid using FILTER as a filter argument in DAX - DAX
- Use variables to improve your DAX formulas - DAX
- Direct Lake overview - Microsoft Fabric
- Develop Direct Lake semantic models - Microsoft Fabric
- How Direct Lake works - Microsoft Fabric
- Integrate Direct Lake Security - Microsoft Fabric
- Configure incremental refresh and real-time data for Power BI semantic models - Power BI
- Configure incremental refresh for Power BI semantic models - Power BI
- Lakehouse and Delta Tables - Microsoft Fabric
- Optimize Delta Lake tables with V-Order in Fabric - Microsoft Fabric
- Performance Guidelines - Microsoft Fabric
- Best practices for Kusto Query Language queries - Kusto
- Spark errors overview in Microsoft Fabric - Microsoft Fabric