Microsoft introduced DAX User-Defined Functions (UDFs) as part of the September 2025 Power BI update, bringing a major improvement in how DAX logic is written and managed. With this feature, you can now create custom functions directly in DAX, similar to how functions work in programming languages. This marks an important step in making DAX more structured and easier to work with, especially for complex models.
Until now, developers often had to repeat the same logic across multiple measures, which made models harder to maintain and scale. With DAX User-Defined Functions (UDFs), you can define logic once and reuse it across different parts of your model. As a result, your calculations become more organized, easier to update, and more consistent across reports.
Key Takeaways:
- Centralized and reusable logic: DAX User-Defined Functions allow you to define logic once and reuse it across multiple measures. As a result, you reduce duplication and keep calculations consistent throughout the model.
- Cleaner and more readable measures: Instead of writing long expressions inside every measure, you can move the logic into functions. This keeps measures concise while improving readability and structure.
- Consistent business logic across the model: When multiple measures rely on the same function, they follow the same calculation pattern. This ensures consistent results and reduces the risk of mismatched logic.
- Better handling of complex calculations: You can break complex logic into smaller functions and combine them when needed. This makes calculations easier to build, understand, and maintain over time.
- Simplified maintenance and updates: When business logic changes, you can update it directly inside the function. Consequently, all related measures automatically reflect the updated logic without extra effort.
What Are DAX User-Defined Functions (UDFs)?
DAX User-Defined Functions (UDFs) allow you to create custom functions in DAX that accept parameters and return calculated results. Instead of writing the same logic repeatedly in different measures, you can define it once and reuse it wherever needed.
In addition, these functions behave like built-in DAX functions. You can pass inputs, apply logic, and even call one UDF inside another. This makes your model more structured and helps you manage complex calculations in a cleaner way.
Key Characteristics of DAX User-Defined Functions (UDFs)
- Parameter-driven logic: Inputs such as measures, columns, or values can be passed into the function, and the result is calculated based on those inputs. This makes the logic flexible and adaptable instead of relying on hardcoded values.
- Reusable across the model: Once a function is defined, it can be used in measures, calculated columns, and visual calculations. This reduces repetition and helps maintain consistency across the model.
- Supports nested logic: One UDF can call another, which makes it easier to break complex calculations into smaller, manageable parts. This improves readability and simplifies maintenance.
- Acts like native DAX functions: After creation, a UDF behaves like a built-in DAX function. It becomes part of the model and can be reused across different calculations in a structured way.
Syntax: How to Write a DAX UDF
UDFs use the DEFINE FUNCTION keyword with an arrow notation (=>) to separate the function signature from its body.
Basic Structure of a DAX UDF
A DAX User-Defined Function typically includes the following parts:
- Function declaration using DEFINE FUNCTION
- Function name
- Input parameters (optional)
- Arrow (=>) to define the function body
- Expression that returns the result
Example Structure
DEFINE
FUNCTION AddTax(amount) =>
amount * 1.1
This example defines a simple function that takes an input value and applies a 10% increase. Once defined, the function can be reused across different calculations.
Power BI Paginated Reports: Everything You Need to Know
Discover all the essentials of Power BI Paginated Reports to create detailed, print-ready data insights for comprehensive business reporting.
How to Enable DAX User-Defined Functions (UDFs) in Power BI
DAX User-Defined Functions (UDFs) are currently available as a preview feature, which means they are not enabled by default in Power BI. Before creating or testing functions, this setting needs to be turned on from the options menu.
Steps to Enable
1. Open Power BI Options
Go to File → Options and Settings → Options. This opens the main settings panel where preview features can be managed.
2. Navigate to Preview Features
In the options window, select the Preview Features section. This is where all upcoming or experimental features are listed.
3. Enable DAX User-Defined Functions (UDFs)
Find the option for DAX User-Defined Functions and enable it. This activates support for creating and using custom functions in DAX.
4. Restart Power BI
Close and reopen Power BI so the changes take effect. Once restarted, the feature will be available in your modeling environment.
Partner with Kanerika to Modernize Your Enterprise Operations with High-Impact Data & AI Solutions
Understanding Parameters in DAX User-Defined Functions (UDFs)
Parameters are where UDFs get more nuanced. Understanding the two dimensions, type and evaluation mode, is important before writing anything context-sensitive, like time intelligence.
Parameter Types in DAX UDFs
| Parameter Type | What It Accepts | How It Is Used in Practice | Example Scenario |
| Scalar | Single value (number, text, date, boolean) | Used when the function expects one value at a time | Passing [Net Sales] into a function to apply a calculation like tax or discount |
| Table | Entire table as input | Used when calculations need to iterate over rows or apply table-level logic | Passing a filtered table into a function for aggregation |
| Variant (flexible type) | Multiple possible types | Used when the function should handle different kinds of inputs without strict type enforcement | A generic function that works with both numeric and text-based inputs |
Parameter Modes in DAX UDFs
| Parameter Mode | How It Works | Evaluation Timing | When to Use | Example Scenario |
| Value (default) | Input is evaluated first, then passed to the function | Before function execution (eager evaluation) | When working with simple values that do not depend on context | Passing a fixed value or a pre-calculated measure |
| Expression | Input is passed as an unevaluated expression and evaluated inside the function | During function execution (lazy evaluation) | When calculation depends on filter context or row context | Passing [Net Sales] into an MTD function using CALCULATE |
Creating Your First DAX User-Defined Function (UDF)
A UDF is created using the DEFINE FUNCTION syntax. You give it a name, define parameters, and write the logic after the arrow (=>). Once registered, it is available across the model like any other function.
Example: Simple UDF
DEFINE
FUNCTION AddTax(amount) =>
amount * 1.1
This function takes an input value and increases it by 10%. The logic is simple, but it shows how reusable calculations can be defined once and applied multiple times.
Steps to Create a UDF
1. Open DAX Query View
Go to the DAX Query View in Power BI. This is where functions can be defined and tested.

2. Define the function
Write the function using the DEFINE FUNCTION syntax with a parameter and calculation logic.

3. Update the model
Run or update the model so that the function gets registered and becomes available for use.

4. Verify function creation
Check the model explorer to confirm that the function appears under the functions section.

Testing DAX UDFs in DAX Query View
Before using a function in a report, test it in DAX Query View using EVALUATE.
How to Test a UDF
1. Call the function using EVALUATE
Use the EVALUATE statement in DAX Query View to execute the function and return results. This allows you to test the function independently without adding it to a measure or visual.
2. Pass sample input values
Provide different input values as parameters to check how the function behaves. Testing with multiple values helps confirm that the function works correctly across different scenarios.
3. Run the query
Execute the query to display the output in a tabular format. This makes it easier to verify whether the results match the expected logic defined in the function.
Example: Testing the Function
EVALUATE
{
AddTax(10),
AddTax(20)
}
This returns results where each input is increased by 10%, confirming that the function works as expected.

Building a Real Example Using DAX UDFs (MTD Calculation)
MTD calculations are one of the most repeated patterns in Power BI. Most models have versions of this logic scattered across multiple measures. UDFs are a clean fix for that.
Step 1: Define the MTD Function
Create a function that accepts a measure as input and applies MTD logic using CALCULATE and DATESMTD.
DEFINE
FUNCTION GetMTD(m) =>
CALCULATE(
m,
DATESMTD(‘Date'[Date])
)
This function takes a measure as input and returns its MTD value based on the date context.

Step 2: Use the Function in a Measure
Now call the function inside a measure by passing an existing metric.
MTD Net Sales = GetMTD([Net Sales])
This replaces the need to write full MTD logic inside each measure.

Step 3: Apply to Multiple Measures
The same function can be reused for other measures as well.
MTD Gross Sales = GetMTD([Gross Sales])
MTD Profit = GetMTD([Profit])
This ensures that all MTD calculations follow the same logic.

Step 4: Observe the Output
When used in a visual with a date field:
- Values reset at the beginning of each month
- Values accumulate within the month
- Output matches standard MTD behavior

Fixing Context Issues Using Expression Parameters
When you first write a function like GetMTD, the results may look wrong. The usual reason is how the parameter gets evaluated. By default, DAX evaluates the input before passing it into the function. So by the time CALCULATE runs, the measure is already a static number. DATESMTD has nothing left to filter.
Here is what the default behavior looks like:
dax
FUNCTION GetMTD(m) => — value mode (default)
CALCULATE(m, DATESMTD(‘Date'[Date]))
To fix it, define the parameter as an expression so DAX passes it unevaluated and lets the function control when it runs:
dax
FUNCTION GetMTD(m AS ANY REF EXPRESSION) =>
CALCULATE(m, DATESMTD(‘Date'[Date]))
What changes after this fix:
- Correct MTD calculation: The measure now evaluates inside CALCULATE, so DATESMTD applies the right date filter context. Results reflect true MTD behavior instead of a static or incorrect value.
- Proper accumulation: Values increase day by day within the month and reset at the start of the next month, exactly as expected.
- Consistent across visuals: The function produces stable results regardless of how the visual is structured, sorted, or filtered. Evaluation happens inside the function every time.
The AS ANY REF EXPRESSION syntax is the key. Without it, time intelligence functions inside UDFs will almost always return wrong results.
Validating Results in Report View
After fixing the parameter evaluation mode, validate the function in an actual report before relying on it in production.
How to Validate the Results
1. Add a date field to the visual
Use a column from the date table (for example, Date) to create a time-based view of the data.
2. Add the base measure and UDF measure
Include both the original measure (such as Net Sales) and the new UDF-based measure (MTD Net Sales) in the visual.
3. Compare the outputs
Observe how the UDF-based measure behaves in comparison to the base measure across dates.

Reusing DAX User-Defined Functions (UDFs) Across Measures
Once the function is validated, apply it across other measures by passing different inputs.
Example: Reusing the Same Function
MTD Net Sales = GetMTD([Net Sales])
MTD Gross Sales = GetMTD([Gross Sales])
MTD Profit = GetMTD([Profit])
Each measure uses the same function, but the input changes based on the requirement.
Advanced Use Cases of DAX User-Defined Functions (UDFs)
| Use Case | What You Do | How It Works in Practice | Practical Example |
| Reusable time intelligence | Define functions for MTD, YTD, or rolling calculations | Create one function (e.g., GetMTD) and reuse it across multiple measures instead of rewriting CALCULATE + DATESMTD each time | MTD Net = GetMTD([Net Sales]) MTD Gross = GetMTD([Gross Sales]) |
| Standardizing business rules | Centralize logic like tax, discount, or margin calculations | Define rules once in a function and apply them across all relevant measures to ensure consistency | Final Price = ApplyDiscount([Sales]) used across reports |
| Layered (nested) calculations | Break complex logic into smaller functions and combine them | Create smaller functions and call them inside another function to build more complex calculations step by step | FinalMetric = ApplyTax(ApplyDiscount([Sales])) |
| Dynamic calculations using parameters | Pass different measures or values into the same function | Use parameters so the same function adapts based on input instead of creating separate measures | Adjusted = AdjustValue([Net Sales]) Adjusted = AdjustValue([Profit]) |
Practical Impact of DAX UDFs in Power BI Projects
DAX UDFs change how complex models should be built. Some practical implications:
- Simpler measures: Measures become declarations of intent rather than walls of DAX. MTD Net Sales = GetMTD([Net Sales]) is easier to read and audit than the full CALCULATE expression every time.
- Faster onboarding: New team members can understand measure logic without tracing through identical expressions scattered across the model. The function is the documentation.
- Safer updates: Business rules encoded in a single function are safer to change than the same logic duplicated across 15 measures. One change, one place, no missed copies.
- Better model governance: UDFs create a natural place to enforce standards. If the company’s MTD calculation has a specific rule, that rule lives in one function. Every measure that calls it follows it.
For organizations running complex Power BI environments with many measures and shared business logic, UDFs are a meaningful structural improvement. Teams working on Microsoft Fabric and Power BI at scale, particularly in data engineering and AI-driven analytics contexts, will find that UDFs reduce the overhead of maintaining large semantic models significantly.
Power BI Paginated Reports: Everything You Need to Know
Discover all the essentials of Power BI Paginated Reports to create detailed, print-ready data insights for comprehensive business reporting.
Kanerika: Your Trusted Partner for Power BI & Microsoft Fabric
Kanerika is a leading Data & AI solutions company specializing in Power BI, Microsoft Fabric, and AI-driven analytics. We empower businesses with purpose-built solutions designed to address unique challenges, enhance decision-making, and improve business intelligence.
With expertise across multiple industries, we have delivered impactful Power BI solutions that drive real value. Our team helps organizations transition from legacy and outdated data platforms to modern, scalable solutions like Power BI and Microsoft Fabric, ensuring faster insights and better efficiency.
We also develop custom automation solutions, streamlining data migration, reporting, and analytics to help businesses stay competitive in a data-driven world. Our solutions are designed for seamless integration, optimized performance, and future scalability.
Partner with Kanerika to harness the full potential of Power BI and Microsoft Fabric and transform your data strategy for long-term success. Let’s build the future of analytics together!
Take Your Business to the Next Level with Innovative Power BI Solutions!
Partner with Kanerika today.
FAQs
How are UDFs different from calculation groups?
Calculation groups apply fixed logic uniformly across multiple measures. UDFs accept parameters, so the same function can return different results depending on what you pass in. UDFs are better when logic needs to vary based on input.
What are DAX User-Defined Functions (UDFs) in Power BI?
DAX UDFs are custom, reusable functions you define in the DAX language. They accept parameters, apply logic, and return results. Once created, they behave like built-in DAX functions and can be used across measures, calculated columns, and visual calculations.
Why are my MTD calculations returning wrong results with UDFs?
This is almost always a parameter evaluation mode issue. By default, parameters are evaluated as values before entering the function, which means DATESMTD has no measure to filter. Fix it by defining the parameter as AS ANY REF EXPRESSION so the measure evaluates inside CALCULATE.
Are DAX UDFs available in all Power BI environments?
As of September 2025, UDFs are a preview feature. They need to be enabled manually via File → Options and Settings → Options → Preview Features. They are available in Power BI Desktop and should extend to other DAX-compatible environments over time.
What happens to all measures that use a UDF when I update the function?
All measures that call the function automatically reflect the updated logic. You update the function once and the change propagates everywhere it is used.



