How to fix Microsoft Fabric CapacityLimitExceeded (subCode 0) without doubling your SKU
When a Microsoft Fabric capacity runs out of future borrowing headroom, users and pipelines hit a blocking error: CapacityLimitExceeded (often shown with subCode: 0, HTTP 429 Too Many Requests, or "Cannot load model / Your capacity has exceeded its available resources"). Even more confusingly, admins frequently see CapacityLimitExceeded block lightweight metadata calls, preview features, or operations documented as non-billable (0 CU).
Before you upgrade your SKU and double your monthly Azure bill, understand the exact math behind Fabric's three throttling thresholds—Interactive Delay (10 minutes), Interactive Rejection (60 minutes), and Background Rejection (24 hours)—and how to isolate the offending items in under five minutes.
What CapacityLimitExceeded (subCode 0) actually means
In Microsoft Fabric, exceeding 100% utilization for a single 30-second window does not trigger an error. Fabric lets workloads borrow capacity from future windows (smoothing and carryforward) and only throttles when accumulated borrowed debt crosses strict time-horizon limits (Microsoft Learn: The Fabric throttling policy).
Every F-SKU supplies a fixed number of Capacity Unit seconds (CU-seconds) per 30-second window: F2 provides 60 CU-s, F32 provides 960 CU-s, and F64 provides 1,920 CU-s. When smoothed interactive + background usage exceeds 100%, the excess accumulates as carryforward debt across three escalating stages:
| Throttling Stage | Carryforward Debt Threshold | CU-Seconds Debt on F32 / F64 | System Behavior & User Impact |
|---|---|---|---|
| Stage 0: Burst / Carryforward | >100% current window, <10 min future debt | 1 – 19,199 CU-s (F32) 1 – 38,399 CU-s (F64) | Zero impact. Queries and refreshes run at full speed while debt burns down during quieter windows. |
| Stage 1: Interactive Delay | 10 minutes to 60 minutes of future capacity | 19,200 – 115,199 CU-s (F32) 38,400 – 230,399 CU-s (F64) | 20-second artificial delay injected before every interactive query (Power BI visuals, DAX, SQL endpoint). Reports feel sluggish. |
| Stage 2: Interactive Rejection | ≥ 60 minutes (1 hour) of future capacity | ≥ 115,200 CU-s (F32) ≥ 230,400 CU-s (F64) | Hard rejection (CapacityLimitExceeded) for all interactive requests. Background jobs continue unless Stage 3 is hit. |
| Stage 3: Background Rejection | ≥ 24 hours of future capacity | ≥ 2,764,800 CU-s (F32) ≥ 5,529,600 CU-s (F64) | Total capacity lockdown. Both interactive queries and new scheduled refreshes, Spark jobs, and pipelines are rejected immediately. |
Burndown Minutes = (Accumulated Carryforward CU-Seconds − Threshold CU-Seconds) ÷ [(1.0 − Current Baseline Utilization %) × SKU CUs × 60]
Why "non-billable" (0 CU) and preview operations still fail with CapacityLimitExceeded
A common question on Reddit and the Fabric forums is why a preview feature (such as Ontology Discovery, AI skills, GraphQL metadata calls, or OneLake shortcut checks) documented as non-billable or 0 CU still fails with CapacityLimitExceeded (subCode: 0). Two architectural rules cause this:
- Downstream billable operations under the hood: Even when a top-level preview wrapper is marked 0 CU, running it almost always triggers underlying OneLake storage reads, SQL analytics endpoint metadata queries, KQL scans, or semantic model XMLA queries that do emit CU-seconds and obey interactive throttling.
- Gateway state rejection precedes operation metering: Once a capacity crosses the 60-minute Interactive Rejection threshold, the capacity admission controller rejects incoming interactive requests at the gate—whether the request itself would cost 0 CUs, 1 CU, or 500 CUs.
Step-by-step: Isolate the top 3 offending items in Capacity Metrics
In 90% of throttled tenants we audit (see our sample 48h check report), throttling comes from 1 to 3 runaway items—not organic user growth:
Step 1: Open Compute → Throttling → Explore
In the Microsoft Fabric Capacity Metrics app, select your capacity on the Compute page. Click Throttling in the multi-metric ribbon and check Interactive delay %, Interactive rejection %, and Background rejection %. Right-click the first 30-second timepoint where Interactive rejection % crossed 100% and select Drill through → Timepoint detail (or click Explore).
Step 2: Separate Interactive culprits from 24-hour Smoothed Background culprits
On the Timepoint Detail page, sort both the Interactive operations and Background operations tables by Total CU (s) descending and inspect % of Base Capacity:
- If Interactive operations dominate: Look for a single Power BI report firing uncached DirectQuery/Direct Lake storms, a high-cardinality matrix visual with 15+ DAX measures and no Top-N filter, or an external script polling the XMLA/SQL endpoint.
- If Background operations dominate: Because background jobs smooth over 24 hours, the job that pushed you over 100% at 11:00 may have run yesterday afternoon. Check the Start Time column. The usual culprits are Dataflow Gen2 refreshes with staging enabled, full semantic model refreshes, and unstopped Spark sessions.
Step 3: Enable Surge Protection in the Admin Portal
In Fabric Admin Portal → Capacity settings → [Your Capacity] → Surge protection, set a background consumption threshold so runaway background jobs are rejected before they accumulate 60 minutes of carryforward debt and lock out interactive Power BI report viewers.
Emergency recovery vs permanent fix
- Temporary SKU burndown (Recommended): Scale the capacity up one tier (e.g., F32 → F64) in Azure for 1–2 hours. Doubling the SKU immediately halves the relative carryforward debt percentage, dropping the capacity below the 60-minute rejection line while debt burns down. Scale back down once Carryforward % reaches 0%.
- Avoid blind Pause/Resume to clear debt: As shown in our pause smoothing and carryforward billing guide, pausing resets the operational lock, but Azure immediately bills the entire accumulated carryforward balance as a lump sum at the standard PAYG rate ($0.18/CU-hour; pricing varies by agreement and currency).
After recovery, drop your 14-day export into our free Excel Fabric Capacity Savings Checker and review our P1 to F64/F32 sizing guide and F-SKU PAYG vs Reserved pricing table to isolate noisy ETL onto a small secondary capacity.
Frequently asked questions
What causes Fabric CapacityLimitExceeded with subCode 0?
CapacityLimitExceeded (subCode 0) occurs when your Microsoft Fabric capacity's accumulated carryforward overage exceeds 60 minutes of future capacity (triggering Interactive Rejection for reports and queries) or 24 hours of future capacity (triggering Background Rejection for refreshes, pipelines, and notebooks).
Why do I get CapacityLimitExceeded when my average daily CU utilization is only 40%?
Even if your 24-hour average utilization is 40%, a cluster of heavy interactive DAX queries, SQL endpoint scans, or overlapping background refreshes can push smoothed utilization above 100% long enough to accumulate 60 minutes of carryforward debt during peak hours.
Does pausing and resuming a Fabric capacity fix CapacityLimitExceeded throttling?
Yes, pausing and resuming resets the capacity's real-time throttling state so queries run immediately upon resume. However, Azure immediately bills all unamortized smoothed usage and carryforward overage debt as a one-time charge when you pause.
Get a free 48h Fabric capacity check
Send a screenshot or CSV export of your Fabric Capacity Metrics app (Compute page, last 14 days) to [email protected]. Within 48 hours you get a one-page diagnostic with your target SKU, pause schedule, carryforward risk, and monthly saving. No tenant access, no call, no cost.
Run the free savings estimator → Download the Excel checker (.xlsx) →