clement13.net
Original photo: Sablier de bureau : le temps que l'on attend s'écoule grain par grain.
Description
Sablier de bureau : le temps que l'on attend s'écoule grain par grain.
Source
Suohros · original page
Licence
CC0 Public domain
Original photo, unretouched. The background is a version of it stylised by the site.

Performance and Data Volume

This theme measures how long the user waits (opening, clicking a filter, export) and the product's ability to keep its promise as data grows. It covers…

Guide≈ 6 min readCheckedCheck doneFacts, figures and references were checked against the sources cited in the page.Written with AI assistance; sources are cited at the bottom of the page. An error? Report it via clement13.net.Reading
In brief

This theme measures how long the user waits (opening, clicking a filter, export) and the product's ability to keep its promise as data grows. It covers column cardinality, model size, storage modes (Import, DirectQuery, Dual, Direct Lake), aggregations, number of visuals, and query analysis (Performance Analyzer, DAX Studio, query plans).

On this page

Level: 🟢→🔴 · Theme code: PRF

1. Why this theme#

A slow report is not “used less”: it is bypassed (Excel export, direct SQL query, local copy), which destroys governance. Commonly accepted usage benchmarks: below about 1 s, the user does not perceive waiting; around 10 s, they disengage (orders of magnitude from ergonomics research; adapt as needed). Performance of an Import model depends first on cardinality and size (VertiPaq columnar engine), then DAX quality (DAX), then the page (number of visuals).

2. What the theme measures#

  • Axis: from “it's lagging and we don't know why” to response time guaranteed by a measured pipeline budget.
  • Key indicators: page render time (P50/P95), DAX query duration per visual, model size (MB/GB), refresh duration, share of DirectQuery requests > 3 s.
  • Units: seconds, MB, number of visuals per page.

3. The 5 levels#

Level Short name Promise Typical indicator (order of magnitude)
1 Suffered The report opens “whenever it feels like it”; no one knows whether that is normal. No measurement; complaints
2 Measured We know which page and which visual are slow, and the opening time is known. Typical page < 10 s; manual measurement
3 Managed Common pages display in under 3 s on a realistic dataset, and we know why. P95 page < 3 s; model < 70% of license limit
4 Budgeted A performance regression is detected before production deployment. Time budget per page checked at every release
5 Guaranteed Nominal load and projected 12-month growth are absorbed without noticeable degradation. P95 page < 1–2 s at nominal load; load ramp-up test

4. Milestones by level#

ID Milestone Verifiable evidence
BI-PRF-1.1 The report opens and remains usable on the full dataset Successful opening in production
BI-PRF-1.2 Users can report slowness through a known channel Support channel / form
BI-PRF-1.3 Storage mode (Import/DirectQuery) is chosen deliberately Mention in the model sheet
BI-PRF-2.1 Performance Analyzer used on the main pages Export of durations by visual
BI-PRF-2.2 Unused columns are removed from the model No unused column > 1% of size
BI-PRF-2.3 Model size and refresh time are known and recorded Up-to-date model sheet
BI-PRF-2.4 A slowness threshold (“too slow”) is defined Written threshold, e.g., page > 5 s
BI-PRF-3.1 High-cardinality columns handled (timestamp split into date + time, IDs not loaded) Cardinality analysis (VertiPaq Analyzer)
BI-PRF-3.2 Appropriate numeric types and calculated columns avoided in favor of the source Review of calculated columns
BI-PRF-3.3 Number of visuals per page capped and heavy pages split Reference page < 10–15 visuals
BI-PRF-3.4 Costly DAX identified with DAX Studio (Server Timings: FE vs SE) Timing capture before/after
BI-PRF-3.5 Aggregations or aggregate tables for large fact tables Aggregated table + measures that use it
BI-PRF-4.1 Realistic test dataset (volume ≥ production) Loaded test environment
BI-PRF-4.2 Performance budget run on each version (reference queries) Results logged by version
BI-PRF-4.3 Regression report: time variation between two versions Comparison in release review
BI-PRF-4.4 Mixed modes (Dual, composite) chosen with measured justification Documented decision
BI-PRF-5.1 Multi-user load test (realistic concurrency) Test report
BI-PRF-5.2 12-month growth projection, reviewed each quarter Projection document
BI-PRF-5.3 P95 target < 1–2 s met on the 5 most viewed pages Production measurement
BI-PRF-5.4 Continuous optimization: table of the 10 most expensive queries Monthly review of slow queries

5. Detailed reading by level#

🟢 Level 1 — Suffered#

  • Signs: “it's been slow since Monday,” no numbers. Or worse: no one complains because no one uses it.
  • Difficulty: 1/5 · Effort: 1/5.

🟢 Level 2 — Measured#

  • Signs: Performance Analyzer used, model size known, unused columns removed (size reduction often 20 to 50% in a model never cleaned up — order of magnitude).
  • Gain: we stop guessing. Limit: each measurement is point-in-time.
  • Difficulty: 2/5 · Effort: 2/5.

🟡 Level 3 — Managed#

  • Signs: we can read the difference between formula engine time (Formula Engine) and storage engine time (Storage Engine); we handle cardinality first (a per-second timestamp over 100M rows ruins compression), then DAX, then the page. Aggregations cover frequent queries.
🧪 Example

SFA thread: DateHeureVisite (second-level precision) produced 12M distinct values. Split into DateVisite (1,500 values) and HeureVisite (86,400 → reduced to minute level: 1,440), model size drops from 2.1 GB to 0.9 GB (illustrative figures).

-- Dans DAX Studio : lire les timings serveur
EVALUATE
SUMMARIZECOLUMNS (
    'DIM_DATE'[Mois],
    'DIM_COMMERCIAL'[Region],
    "Visites", [Nb Visites]
)
  • Gain: optimization is targeted. Limit: without a budget, performance degrades version after version.
  • Difficulty: 3/5 · Effort: 3/5.
⚠️ Pitfall

Symptom: the report is fast in development, slow in production. Cause: reduced test dataset; exploding cardinality only appears at real volume. Remedy: test with production-scale volume (or a proportional sample).

🟡 Level 4 — Budgeted#

  • Signs: every release runs a set of reference queries (e.g., 20 DAX queries extracted from Performance Analyzer, replayed by script) and compares durations with the previous version. A threshold breach blocks or alerts.
  • Gain: regression is visible before the user sees it.
  • Limit: the budget becomes outdated if usage changes.
  • Difficulty: 4/5 · Effort: 4/5.

🔴 Level 5 — Guaranteed#

  • Signs: concurrent load testing, growth projection, P95 target maintained. Architecture choices are owned: Import for hot data, DirectQuery/Direct Lake for very large volumes, automatic or manual aggregations, partitions.
  • Gain: performance stops being a surprise.
  • Limit: cost (capacity, CST); freshness/speed trade-off.
  • Difficulty: 5/5 · Effort: 5/5.
💡 Expert tip

In a DirectQuery model, performance is decided in the database: columnstore or covering indexes, up-to-date statistics, simple views without scalar functions. Check the emitted SQL (Profiler/Extended Events) before “tuning” DAX.

✅ Good practice

A page rule: one visual = one question. Replace ten KPI cards with one matrix, and unnecessary slicers with a page filter.

🤖 AI

Assistants can explain a query plan and suggest DAX rewrites; they do not know your real cardinality. Paste Server Timings, not just code.

6. Partial achievement and rating#

Common rule. A “partial 5”: P95 is met under nominal conditions but no load test has been run (BI-PRF-5.1 = 0), growth projection exists (5.2 = 1), P95 target is met on 3 pages out of 5 (5.3 = 0.5); level 5 is not achieved as long as one milestone is at 0.

7. Moving to the next level#

Possible means (optional):

Transition Possible levers
1 → 2 Performance Analyzer, VertiPaq Analyzer, removal of unused columns
2 → 3 Cardinality reduction, DAX Studio, aggregations, limiting visuals
3 → 4 Large test dataset, reference queries replayed by script, pipeline thresholds
4 → 5 Load testing, capacity planning, partitioning, automatic aggregate tables

Pitfalls:

  • Optimizing the measure that costs 40 ms while the page launches 25 visuals: always look first for the largest contributor.
  • Goodhart: a “< 3 s” budget met by hiding slow visuals behind bookmarks: slowness is hidden, not solved.
  • Measurements on shared capacity vary with surrounding load: measure in alternation, multiple times, never with a single run.

8. See also#

✻ Written by Claude Sonnet 5.5