

- Description
- Rivage d’un grand lac agité sous un ciel chargé, avec des arbres nus et des enrochements.
- Source
- SAF1999 · original page
- Licence
- CC0 Public domain
OneLake + SaaS Mobile Apps: difficulties and pitfalls
You will be able to anticipate structural difficulties: capacity (CU), throttling, API quotas, freshness, identity, field quality, multitenant, hidden costs, governance, lock-in…
In brief
- You will be able to anticipate structural difficulties: capacity (CU), throttling, API quotas, freshness, identity, field quality, multitenant, hidden costs, governance, lock-in, skills.
- You have a catalog of 36 pitfalls in symptom / cause / remedy format, numbered P01 to P36, to copy into your checklist (project checklist).
- You will be able to diagnose a capacity incident and a discrepancy in numbers without blaming the wrong link in the chain.
- Context: Overview and architecture. Volatile facts verified in October 2026 (status 2026-10); exact thresholds must be rechecked in the documentation before any sizing.
On this page
- 1. Capacity and CU
- 2. Throttling and smoothing
- 3. Direct Lake: fallback and guardrails
- 4. SaaS API quotas and constraints
- 5. Latency and freshness
- 6. Identities and consent
- 7. Field data quality
- 8. Multi-tenant and Multi-client
- 9. Hidden Costs
- 10. Governance and Lock-in
- 11. Skills and Organization
- 12. Pitfall Catalog
- 13. In-Context Diagnosis
- 14. Summary Notes
- 15. See also
Level: 🟢→🔴
1. Capacity and CU#
🟢 Novice.
Fabric is not billed per query but by capacity: an “F” SKU (F2, F4, F8… F8192) provides a number of Capacity Units (CU) per second, shared across all workspace workloads: pipelines, Spark, dataflows, SQL queries, refreshes, reports, Copilot. An F64 provides 64 CU.
Public pricing orders of magnitude (status 2026-10, to be rechecked in your region and currency): about USD 0.18 per CU per hour in pay-as-you-go in a reference U.S. region, billed by the second with a one-minute minimum, or about USD 263 per month for an F2 running 24/7; a one-year reservation lowers cost by about 40%. Capacities can be paused (you do not pay compute during the pause, but already accumulated smoothed consumption is billed when pausing, and storage remains billed) or resized (SKU change) when load varies.
Other reference points:
- The F64 threshold has licensing significance: from F64 upward (formerly P1), readers of shared content do not need a Power BI Pro license; below that, each reader must have one (status 2026-10, to be verified against current licensing policy — see Cost, Licensing, and Capacity).
- Direct Lake guardrails depend on SKU (maximum memory, number of files, rows per table): F2–F32: 300 million rows per table; F64: 1.5 billion (status 2026-10).
- Copilot and data agents can be used starting at F2 (availability extended to all paid SKUs since April 30, 2025; status 2026-10) and consume CU.
Choosing SKU based on data size rather than load shape (refresh peaks, user concurrency). A 200 GB warehouse viewed by 20 people requires little; 500 users opening a report at 8:30 a.m. requires a lot.
2. Throttling and smoothing#
🟡 Practitioner.
Smoothing: Fabric smooths consumption over time. Background operations (refreshes, pipelines, scheduled Spark) are smoothed over 24 hours; interactive operations (report queries) over a shorter window (from a few minutes to one hour, depending on load). So you can temporarily exceed capacity without immediate consequences by “borrowing” from the future.
Throttling: when consumption debt exceeds certain thresholds, the platform delays then rejects operations. Order-of-magnitude escalation (to be rechecked in Fabric “Throttling” documentation): overrun up to 10 minutes of future capacity: no penalty; 10 to 60 minutes: interactive operations are delayed; beyond that, they are rejected; if debt exceeds 24 hours, background operations are also rejected.
Concrete consequences:
- A large notebook launched at 8 a.m. can degrade reports at 11 a.m.: the bill comes later.
- A faulty refresh loop (automatic retries) can consume all available credit.
- “Slow Monday morning” reports are often a symptom of debt carried over from the weekend.
Tools: Fabric Capacity Metrics app (consumption by item, operation, user, overruns), capacity alerts, and pipeline and Spark logs. No monitoring, no control (Operations, Monitoring, and Capacity).
Split into two capacities: one “user prod” and one “ingestion/ad hoc.” This is the most effective defense against the noisy neighbor, often cheaper than oversizing a single capacity.
3. Direct Lake: fallback and guardrails#
🟡 Practitioner.
Two variants coexist (status 2026-10): Direct Lake on OneLake, which never falls back to DirectQuery and fails explicitly if a guardrail is exceeded, and Direct Lake on SQL analytics endpoint, which falls back to DirectQuery if the source is a SQL view, if the endpoint applies SQL RLS, or if an SKU guardrail is exceeded (“Direct Lake behavior” setting). Fallback is silent for the user: the report simply becomes slow and loads the SQL source.
Typical causes of slowness or failure: too many small Parquet files (file-count limit exceeded), non-optimized tables (no V-Order, poorly sized row groups), overly wide columns (very long strings, 32,764-character limit), SKU maximum memory exceeded (excessive paging), unsupported types.
Compact gold tables after each major load (OPTIMIZE), keep reasonably sized files, avoid non-materialized views as a model source, and monitor “reframing.” See Microsoft documentation “Cross-workload table maintenance and optimization” (status 2026-10).
4. SaaS API quotas and constraints#
🟡 Practitioner.
The bottleneck in a SaaS project is often not Fabric but the vendor:
- Call quotas per day/hour/minute, per organization or integration user; 429/503 errors to handle with exponential backoff and resume.
- Pagination: expiring cursors, 200-record pages, page drift if data changes during extraction.
- Maintenance windows and API degradation on high-load days (start of month, close periods).
- Volume limits per export, per query, per object; computed fields not filterable server-side.
- API costs billed by some vendors beyond a package limit.
- API deprecation: retired versions, new mandatory tokens; read the end-of-life schedule.
- Interface contract: the vendor does not commit to your analytics use case; clarify contractual support.
An SFA offers 100,000 calls per day. A “visit” object at 200 per page = 5,000 calls per million rows for a full load. A daily full load of 5 million rows = 25,000 calls: feasible, but a full replay of 12 months of history could consume quota needed by other integrations. (Illustrative numbers.)
5. Latency and freshness#
🟡 Practitioner.
Freshness is a sum of latencies, and the longest one decides:
Field entry -> mobile sync -> SaaS back end -> API/export -> Fabric ingestion
(min…days) (min…h) (s) (min…h) (min)
-> silver/gold transformation -> model reframing -> report cache
(min) (s…min) (min if tiles)
What to do: measure end to end (a test record for which you track every timestamp), display last data date in the report, negotiate the real need (does a regional director need real time?), and reserve eventstream for cases with proven value.
Symptom: “the report is wrong” in the morning. Cause: sales reps have not synced yet; data is not wrong, it is missing. Remedy: completeness indicator (number of sales reps synced / expected) and a message in the report.
6. Identities and consent#
🟡 Practitioner.
- Service account: SaaS integration must not depend on one person's account (departure, password rotation, MFA). Prefer a service principal or workspace identity, with secrets in Key Vault.
- Admin consent (OAuth): connections to Dynamics, Salesforce, or Graph require application consent from the tenant admin; plan for the delay.
- Expiring tokens: refresh tokens revoked if account status changes or vendor policy is tightened.
- End-user identity: RLS relies on user address (UPN); however identity in SFA (sales rep code) differs from Entra identity: a mapping table must be maintained.
- External guests (distributor agents, contractors): licensing, security, cross-tenant sharing, delegation (delegated shortcuts in preview, status 2026-10).
- Conditional access / MFA: can block automated calls if misconfigured.
7. Field data quality#
🟡 Practitioner.
Mobile entry generates specific defects: customer duplicates, free-form formats (phone, address), incorrect dates (device clock), GPS coordinates at zero, required fields bypassed (“xxx”), products entered outside the reference catalog, unreadable photos, “ghost” visits created by mistake.
Principles: measure before correcting (null rate, duplicates, out-of-reference entries, by sales rep and by day), do not correct silently (log and make visible), go back to the source (feedback to the field is worth more than any downstream cleanup), and separate technical error (pipeline) from business error (entry). See Data Quality and Testing and Reliability of Numbers.
Duplicate matching, entry anomaly detection, and address normalization are high-gain use cases, to be governed (see AI file).
8. Multi-tenant and Multi-client#
🔴 Expert.
Two “multi” dimensions overlap: that of SaaS (the vendor is multi-tenant; you are one tenant among others) and that of your product (a single Fabric foundation for multiple clients or subsidiaries).
- Isolation: separate workspaces per client, or one workspace with RLS per client; RLS-based isolation requires flawless rigor (one incorrect security table = data leak). Separate workspaces cost more in governance but simplify auditing.
- Client-specific configuration: custom fields specific to each SaaS tenant → shared silver schema with a “key/value” table or dynamic columns; gold keeps standard columns.
- Shared capacity: one heavy client can starve others; consider capacities by segment or internal quotas.
- Regions and compliance: data in the tenant’s region, or the client’s contractual region; Direct Lake requires the same region for source and model.
- Releases: a vendor deploys across all its clients; your integration’s behavior can change on a Monday even if you did nothing.
9. Hidden Costs#
🟡 Practitioner.
| Item | Why it gets overlooked | Order of magnitude / note |
|---|---|---|
| 24/7 capacity for a 4-hour/day workload | People forget to pause or resize | Up to several times the actual need |
| Dev/test capacity | “It’s just for trying things out” | Often 20–50% of production cost, needs managing |
| OneLake storage (long bronze, Delta versions) | Old versions are only released after VACUUM |
Steady growth, often barely visible |
| Network egress and paid API calls | Billed on the vendor side or by a third-party cloud | Must be read in contracts |
| Pro/PPU licenses for creators, readers under F64 | Power BI licenses do not disappear | See Cost, Licensing, and Capacity |
| Copilot and agents (CU) | Consume capacity without a dedicated line item | Can significantly impact peak consumption |
| Human operations time | Not in the tool budget | Often the biggest item |
| Training and upskilling | Underestimated | See §11 |
| Replays and full loads | A simple “reload everything” costs CUs and API calls | Must be measured |
Label each project (naming convention + separate workspaces) so you can allocate consumption, and review sizing every quarter based on applying capacity metrics.
10. Governance and Lock-in#
🔴 Expert.
Governance: without rules, a Fabric tenant becomes “self-service with no owner”; each item has an owner, a status (certified, promoted, trial), and a lifespan. See Governance, Catalog, and Self-Service and Data Governance and Organization. Lineage, catalog (OneLake catalog), and governance (Purview) features help but do not replace discipline; some discovery features (search API, MCP tools) are in preview (status 2026-10).
Lock-in: the storage format (Delta/Parquet) is open; what locks you in is the assembly: Fabric pipelines, gen2 dataflows, Direct Lake semantic model, OneLake security, capacities. Reversibility measure: “if we leave Fabric in 18 months, what do we keep as-is?” (Delta data, Spark notebooks, transformation SQL; to rewrite: orchestration, security model, semantic model). The more “no-code” the software is, the more expensive exit becomes. Compare in the Comparison — OneLake / Fabric vs Managed SQL Server for Power BI Reporting.
Pace of change: Fabric ships continuously; a “preview” feature can change or disappear. Rule: no critical dependency on a preview feature without a fallback plan and without explicit team agreement.
11. Skills and Organization#
🟡 Practitioner.
A OneLake + SaaS project, for a team of 3 to 6 people, requires four skill families: ingestion/API (REST, OAuth, pagination), Delta/Spark/SQL (MERGE, optimization), modeling and DAX, capacity operations (metrics, costs). A team coming from the SQL Server world often masters the second and third by analogy, but not API ingestion or capacity.
Approaches: senior/junior pairing on each building block, a named capacity lead, incident runbook, notebook code reviews, kata on a small scope before the large one. Avoid relying on a single “hero”: the API integration’s truck factor is very often 1.
12. Pitfall Catalog#
🔴 Expert. For each pitfall: symptom, cause, remedy.
12.1 Capacity and Operations#
| ID | Symptom | Cause | Remedy |
|---|---|---|---|
| P01 | Reports are slow or rejected in the morning | Weekend capacity debt (smoothing backlog); a heavy job late at night | Spread out workloads, separate capacities, alert on utilization rate, reschedule jobs |
| P02 | Capacity saturated for no obvious reason | A pipeline or notebook stuck in restart loops | Limit retries, alert on abnormal duration, quota per workspace |
| P03 | Bill higher than budget | Capacity left on continuously, tests left running, Copilot broadly enabled | Automated pause, scheduled resizing, monthly review |
| P04 | Dev and prod interfere with each other | Same capacity for everything | Separate capacities or at least distinct workspaces and schedules |
| P05 | No diagnosis possible afterward | Metrics not retained, no Capacity Metrics app | Install the app, log continuously, keep incident history |
| P06 | Spark starts slowly or fails | Undersized pool/session, concurrency spike | Startup pools, queues, limit interactive sessions |
12.2 Direct Lake and Model#
| ID | Symptom | Cause | Remedy |
|---|---|---|---|
| P07 | Report suddenly slow, SQL source heavily loaded | DirectQuery fallback (Direct Lake on SQL): view, SQL RLS, guardrail | Switch to Direct Lake on OneLake, materialize views, optimize, monitor fallback behavior |
| P08 | Model refresh fails | Guardrail exceeded (files, rows, memory) | Compact, partition Delta, reduce columns, move up SKU |
| P09 | Error “duplicate values on one side” | Duplicate dimension key | Uniqueness test in gold before publishing; quarantine |
| P10 | Column missing or type rejected | Complex Delta type, GUID, binary | Convert in silver/gold |
| P11 | New data not visible | Reframing not triggered, SQL endpoint not synchronized | Enable automatic updates or trigger reframing via API at end of pipeline |
| P12 | RLS bypassed or ineffective | SQL endpoint RLS ignored in Direct Lake on OneLake; readable lakehouse | Define RLS in the model (fixed identity) or OneLake security; restrict workspace roles |
| P13 | Count measures differ by role | Back-filtering from facts to dimensions under RLS | Document, test, and design count measures accordingly |
| P14 | Test→Prod deployment still reads Test | Source rebinding rules unsupported or forgotten | Configure, auto-binding, post-deployment smoke test |
12.3 SaaS Ingestion#
| ID | Symptom | Cause | Remedy |
|---|---|---|---|
| P15 | Missing rows after late sync | Watermark advancing on ingestion date | Window overlap, server date, count-based reconciliation |
| P16 | Ghosts: rows deleted in the app still present | Deletes not exposed by the API | Soft delete, delete stream, periodic key reconciliation |
| P17 | Pipeline broken on a Monday | Field added/renamed by the vendor | Flexible bronze, explicit projection in silver, contract test, alert |
| P18 | Burst of 429 errors | Quota exceeded | Backoff, load spreading, shared token, negotiate a quota |
| P19 | Loading 12 months is impossible | Insufficient API quota | Bulk export on vendor side, stagger loads, use files rather than API |
| P20 | Inconsistent data between two API pages | Mutation during pagination | Stable cursor pagination, closed-window extraction, count-based verification |
| P21 | Token expired, integration dead over a weekend | Personal account or expired secret | Service principal, scheduled rotation, expiration alert |
| P22 | Duplicate rows after a replay | Non-idempotent ingestion | MERGE on natural key, identified batch, silver deduplication |
| P23 | Today's numbers change the next day | Late facts from offline synchronization | Show completeness, stabilize at D+N, double timestamping |
| P24 | Negative durations, one-hour duplicates | Time zones and daylight saving changes | UTC in storage, conversion at display time, tests on boundary dates |
12.4 Quality, Security, and Compliance#
| ID | Symptom | Cause | Remedy |
|---|---|---|---|
| P25 | Duplicate customers in reports | Data entry by multiple sales reps | Mapping table, matching rules, human review of ambiguous cases |
| P26 | Abnormal GPS positions | Device without fix, default values | Plausibility rules, exclusion and reporting |
| P27 | Personal data kept too long | No retention defined in bronze | Durations per table, deletion propagated to all levels |
| P28 | A contractor can see another client's data | RLS-based isolation poorly tested in multi-client setup | Separate workspaces, automated non-leakage tests |
| P29 | Photos or large files slow everything down | Attachments stored in tables | Files outside tables + metadata |
12.5 Organization and Strategy#
| ID | Symptom | Cause | Remedy |
|---|---|---|---|
| P30 | “We don't know where this number comes from” | No lineage, transformations in the report | Upstream logic, Fabric/Purview lineage, measure glossary |
| P31 | Everyone creates their own models | Self-service without governance | Certified model, thin reports, creation roles |
| P32 | Loss of knowledge | Integration owned by one person | Pairing, documentation, versioned code, runbooks |
| P33 | Dependency on a preview feature | Enthusiasm with no fallback plan | Preview dependency register, quarterly review, GA alternative |
| P34 | POC never industrialized | No production entry criteria | Explicit criteria (tests, monitoring, security, operations) |
| P35 | AI gives a confidently wrong answer | Semantic model without description, ambiguous measures | Descriptions, synonyms, test question set, human review |
| P36 | Exiting Fabric is very costly | Logic in proprietary no-code tools | Critical logic in versioned SQL/Spark, documentation of rules outside the tool |
This catalog is neither exhaustive nor ranked by likelihood; from experience, pitfalls P15, P16, P23, and P07 are the most frequent and the most costly in reporting projects based on field application data (judgment, not statistical).
13. In-Context Diagnosis#
🔴 Expert.
Decision tree for “the number is wrong or the report is slow”:
- Wrong or missing? Compare to the source (direct API query or export). If the source differs: ingestion problem (P15–P24). If the source is identical: model/measure problem (P09, P12, P13).
- Slow? Is the report in fallback mode (P07), is the capacity throttling (P01), or is the model exceeding guardrails (P08)?
- Recent or old? Vendor change (P17), deployment (P14), quota exceeded (P18), token (P21).
- Reproducible? For one user only: RLS (P12–P13); for everyone: source or capacity.
“Last week's visits have dropped by 3% since yesterday.” Ranked hypotheses: (1) deletions detected by reconciliation (P16, normal); (2) duplicate correction (P25, normal); (3) a batch rejected to quarantine (P17, abnormal). We check the log table: 412 rows marked deleted, 28 duplicates merged, no quarantine → the drop is expected, document it.
A run log per batch (start, end, rows read/written/rejected, schema version, status) makes it possible to answer in minutes. Without it, every incident is an investigation.
14. Summary Notes#
Expert assessments, contextual (see RATING). Typical severity and probability ratings by category; context: team of 3 to 6 people, SaaS SFA, 100–500 users.
| Difficulty Category | Probability | Severity | Prevention Difficulty | Comment |
|---|---|---|---|---|
| Capacity / throttling | 4/5 | 4/5 | 2/5 | Predictable with monitoring and capacity separation |
| Direct Lake fallback and guardrails | 3/5 | 3/5 | 2/5 | Avoidable through Delta optimization |
| SaaS API quotas | 4/5 | 3/5 | 3/5 | Depends on the vendor |
| Deletions and schema drift | 5/5 | 4/5 | 3/5 | Most frequent; contracts and reconciliation |
| Perceived freshness | 5/5 | 3/5 | 2/5 | Mainly a communication issue |
| Identities and consents | 3/5 | 4/5 | 2/5 | Anticipate with the administrator |
| Field quality | 5/5 | 4/5 | 4/5 | Mostly resolved at the source |
| Hidden costs | 4/5 | 3/5 | 3/5 | Cost allocation and review |
| Lock-in | 3/5 | 3/5 | 3/5 | Depends on how much no-code is used |
| Skills | 4/5 | 4/5 | 4/5 | Takes a long time to build |
15. See also#
- Series: Overview · Architecture · AI · SQL Server in SaaS — difficulties and pitfalls · Comparison · Cross-Cutting Power BI Good Practices · Project Checklist
- Matrices: BI Development · Performance and Data Volume · Data Sources and Contracts · Operations and Support
- Project management: Pitfalls and good practices in project management (cross-functional summary)
- Terms: Glossary
✻ Written by Claude Sonnet 5.5