25 November 2025
Unravelling Complex Models: The Power of DAX UDFs
With the introduction of User-Defined Functions (UDFs) in DAX, released in September 2025, Microsoft has transformed the way semantic models are built and optimised in Power BI and across the Microsoft Fabric ecosystem. UDFs enable the modularisation of repeated logic, reduce measure redundancy, and improve the consistency and maintainability of enterprise models.
This technical article introduces the concept of UDFs in DAX, highlights their main benefits, and analyses their practical impact on semantic modelling.
The TMDL examples included here illustrate their application across different business contexts, with particular emphasis on the financial sector, which forms the basis of the use cases presented.
User-Defined Functions (UDFs) bring to DAX a level of modularity previously unavailable, allowing developers to define parameterised expressions that can be reused across multiple measures and models. In practice, a UDF behaves like a native DAX function such as CALCULATE, FILTER or SUMX, but it is created by the user, who has full control over its parameters, internal logic, and evaluation context.
The basic syntax follows the format:
The symbol => separates the parameter definition from the function body, which contains the DAX logic to be executed. Once created, the function can be invoked in any measure, calculated column or other function simply by passing the required arguments in parentheses, just as with any native function.
UDFs can accept typed parameters, specifying not only the expected value type (for example, SCALAR, TABLE or STRING) but also the parameter-passing mode, which is one of the most important aspects of the new functional model in DAX.
There are two main modes:
VAL (Value): evaluated in advance, within the same evaluation context in which the function is called.
The result is calculated once and passed to the function as a fixed value.
It is ideal for parameters that represent stable results or pre-aggregated values.
EXPR (Expression): evaluated dynamically inside the function, every time it is used within the expression body.
It can produce different results depending on the active filter or row context.
This mode is essential when the function needs to adapt to the execution context, for example in iterations with FILTER, SUMX or AVERAGEX.
The use of VAL and EXPR fundamentally changes the behaviour of the function, especially in scenarios with complex filter contexts.
A VAL parameter behaves like a static variable; an EXPR parameter behaves like a living formula that responds to the context in which it is evaluated.
This distinction enables UDFs to create reusable calculation patterns without sacrificing the dynamism and flexibility of DAX.
For example, while VAL is ideal for functions that receive pre-resolved metrics (such as consolidated totals or averages), EXPR is preferable in functions that need to re-evaluate measures under different filters or specific contexts, such as calculating a metric only for a given country, segment, or period.
User-Defined Functions (UDFs) were designed to integrate natively with the architecture of Power BI and Microsoft Fabric, operating as components within the semantic model.
They can be created and managed directly in Power BI Desktop, the Power BI Service, or specialised tools such as Tabular Editor, and are stored in the model’s TMDL file, becoming part of its structural definition.
This approach ensures portability across environments and consistent behaviour regardless of the dataset’s origin.
UDFs can be stored directly in the semantic model, becoming reusable components that can be called by multiple measures, calculated columns or even other functions, just like native DAX functions.
This integration promotes logical consistency, reduces expression duplication and simplifies maintenance in large-scale projects where coherence across models is critical.
From an architectural perspective, UDFs are fully integrated into the semantic layer and processed by the Formula Engine, just like any other DAX expression.
They can reference measures, columns, tables and variables, and are evaluated dynamically according to the active filter and row context at execution time.
UDFs coexist in a complementary way with Calculation Groups and Field Parameters, offering an additional layer of modularity and logical abstraction.
While Calculation Groups handle calculation patterns applied over existing measures — such as time intelligence variations (YTD, MTD, LY) — UDFs operate at a more fundamental level, encapsulating the internal logic of measures and enabling their reuse across different analytical contexts.
This new paradigm brings DAX closer to more mature functional languages, where business logic is modular, testable and version able, promoting cleaner, more consistent, and more sustainable semantic models in the long term.
In practice, this approach reduces the number of required measures, improves readability, and provides a solid foundation for the governance of complex enterprise models.
The performance of a semantic model in Power BI depends directly on how DAX logic is written and organised.
In many enterprise projects, it is common to find dozens or even hundreds of measures that repeat the same calculation pattern, changing only a filter, a currency, a period, or a product hierarchy.
This traditional approach leads to heavier models, greater maintenance complexity, and a higher risk of inconsistency between similar measures.
From a technical perspective, UDFs are processed by the same Formula Engine that evaluates any DAX expression.
However, their modular structure reduces parsing and evaluation of redundancy, which can have a positive impact on complex models — particularly when multiple measures depend on the same underlying logic.
In addition, UDFs encourage the Formula Engine to reuse sub-expressions, meaning it can share common parts of the execution plan between measures that depend on the same logic, reducing overall computation effort.
More than delivering direct performance gains, UDFs bring structural efficiency.
By centralising logic in reusable functions, the model becomes more predictable and easier to optimise.
Changes can be made in isolation without the need to review dozens of dependent measures, significantly reducing maintenance costs and the risk of logical regression.
A simple example of this efficiency can be seen in a generic function that applies a dynamic context to a metric:
In this case, instead of repeating CALCULATE() with different filters across multiple measures, the modeller defines a single function and calls it in different contexts.
The syntax becomes more concise, the semantics clearer, and the cognitive effort required to read the code is significantly reduced.
In practice, the impact of UDFs is not limited to computational performance:
they also improve human performance, the ability to understand, audit and evolve a model over time.
By eliminating duplicated logic, the analyst gains greater control over metric coherence, and the optimisation process becomes more predictable.
The tests and observations conducted by Marco Russo and Alberto Ferrari (SQLBI, 2025) support this qualitative view: the use of reusable functions leads to semantically stronger models, with tangible gains in clarity, consistency and governance.
Although the direct impact on execution depends on the structure and data volume of each model, the benefits in terms of maintainability and sustainability apply across all scenarios.
In summary, the true value of UDFs lies in their ability to reduce complexity and increase the predictability of model behaviour, while keeping performance and business logic under centralised control, an evolution that naturally moves DAX towards more modular, scalable, and reuse-oriented modelling.
The following examples demonstrate the practical application of VAL and EXPR in enterprise scenarios.
Although some are based on financial metrics, the same approaches apply to any business domain.
ApplyContext
A generic example that demonstrates how to apply a dynamic filter to a metric.
TotalWithDiscount
An example of using VAL parameters, where both values are evaluated prior to the function’s execution.
SalesForPortugal
An example of using EXPR parameters, evaluated within the filter context.
ECL_Total
A more technical example: calculation of Expected Credit Loss (ECL) in a banking scenario.
ConvertToCurrency
A function for parameterised currency conversion.
Analysis — Differences between VAL and EXPR
Model A — Traditional Approach (without UDFs)
Each measure contains its own logic, resulting in code duplication and greater maintenance complexity.
Limitations:
Model B — Modular Approach with UDFs
UDFs allow the base logic to be encapsulated and reused across different measures, reducing duplication and increasing consistency.
Observed Advantages:
|
Criterion |
Model A (without UDFs) | Model B (with UDFs) |
| Code structure | Duplicated |
Centralised |
|
Ease of maintenance |
Low | High |
|
Logic reuse |
Limited | Full |
| Consistency between measures | Medium |
High |
| Adaptability to new contexts | Difficult |
Immediate |
|
Risk of human error |
High | Reduced |
| Overall model complexity | High |
Simplified |
These examples clearly highlight the structural advantage of UDFs: business logic is no longer scattered across dozens of measures but is instead consolidated into reusable functions, promoting transparency, performance, and sustainability of the semantic model.
SQLBI (Russo & Ferrari, 2025) — Introducing User-Defined Functions in DAX
https://www.sqlbi.com/articles/introducing-user-defined-functions-in-dax/
SQLBI YouTube — User-Defined Functions in DAX Explained (2025)
https://www.youtube.com/@SQLBI
Microsoft Learn — DAX Function Reference
https://learn.microsoft.com/power-bi/transform-model/dax/dax-function-reference
Microsoft Learn — Tabular Model Definition Language (TMDL)
https://learn.microsoft.com/power-bi/transform-model/semantic-model-tmdl
DAX Studio — Query Performance Analysis Guide