Semanticus
Documentation

DAX Lab

Author and run DAX, see where the time goes (Formula Engine versus Storage Engine), benchmark cold against warm, and prove a rewrite returns identical numbers before you keep it. DAX Lab is the measure workbench, and every button here is an MCP tool your Claude can drive.

In the Studio

DAX Lab: a query with results, benchmark bars, and an A/B equivalence grid.

Write a query and run it against the connected model, results in a grid. Build a visual from field wells and hover any point to read its exact filter context, so you can see why a number is what it is.

Benchmark a query cold versus warm to expose the worst case, and profile it to see the Formula Engine versus Storage Engine split, the storage-engine scan count and CPU, and the heaviest scans. When a query is Formula-Engine-bound, capture its query plan to find the costly operators.

The optimise-and-prove loop is the headline. Give two or more candidate rewrites, and the engine verifies each returns identical values to the current measure across a group-by matrix you choose, benchmarks only the ones that matched, and surfaces the fastest that genuinely beats the original. Correctness always gates speed, so a faster-but-wrong candidate can never win. Auto-applying the winner is a Pro feature; on the free tier the same run returns the full evidence, paused, so you apply the winner yourself.

Over MCP

The whole suite is dual-drive. Grouped by what they do:

# the optimise-and-prove loop
benchmark_dax           "EVALUATE ROW(\"v\", [Total Sales])"    # measure the baseline
verify_dax_equivalence  exprA=<current>  exprB=<rewrite>  groupBy=[Date[Year], Product[Category]]
optimize_measure        measure:Sales/Total Sales  candidates=[<rewriteA>, <rewriteB>]  verifyGroupBy=[...]

What needs a live connection

Running, benchmarking, profiling, capturing plans, probing and proving equivalence all execute DAX, so they need a live connection: a local Power BI Desktop instance or an XMLA endpoint. The Formula/Storage split and the cold runs want a local Desktop or an admin XMLA endpoint, and degrade gracefully to wall-clock only elsewhere. Authoring is different: validate_dax and lint_dax are fully offline, so you can write and check measures with no connection at all.

Equivalence is only as strong as your matrix

A grand-total-only match is thin evidence, and Semanticus downgrades it to unverified rather than accept it. Pass representative group-by columns so "identical results" means identical everywhere it matters, not just at the total.