$npx -y skills add PatrickGallucci/fabric-skills --skill fabric-rest-api-perf-remediateDiagnose and resolve Microsoft Fabric REST API performance issues including HTTP 429 throttling, long running operation (LRO) timeouts, pagination bottlenecks, and slow API response times. Use when remediate Fabric API latency, capacity throttling, retry-after handling, operation
| 1 | # Microsoft Fabric REST API Performance remediate |
| 2 | |
| 3 | Structured diagnostic workflows and automation scripts for identifying and resolving performance bottlenecks in Microsoft Fabric REST API integrations. |
| 4 | |
| 5 | ## When to Use This Skill |
| 6 | |
| 7 | - API calls to `api.fabric.microsoft.com` are slow or timing out |
| 8 | - Receiving HTTP 429 (Too Many Requests) responses with Retry-After headers |
| 9 | - Long running operations (LRO) polling is inefficient or stalling |
| 10 | - Paginated API responses are taking too long to enumerate |
| 11 | - Bulk workspace or item operations exceed capacity throttle limits |
| 12 | - Entra ID token acquisition is adding unexpected latency |
| 13 | - Spark job submissions return HTTP 430 (TooManyRequestsForCapacity) |
| 14 | - Need to benchmark Fabric REST API throughput for a given capacity SKU |
| 15 | |
| 16 | ## Prerequisites |
| 17 | |
| 18 | - PowerShell 7+ with `Invoke-RestMethod` support |
| 19 | - Microsoft Entra ID app registration with appropriate Fabric scopes |
| 20 | - A valid Bearer token or MSAL-based authentication flow |
| 21 | - Access to at least one Fabric workspace |
| 22 | |
| 23 | ## Diagnostic Decision Tree |
| 24 | |
| 25 | Determine the root cause category before applying a fix: |
| 26 | |
| 27 | ``` |
| 28 | API Call Slow or Failing? |
| 29 | ├── HTTP 429 returned? |
| 30 | │ ├── YES → Throttling. See §1 Throttling Diagnosis |
| 31 | │ └── NO → Continue |
| 32 | ├── HTTP 430 returned? |
| 33 | │ ├── YES → Capacity exhausted. See §2 Capacity Limits |
| 34 | │ └── NO → Continue |
| 35 | ├── HTTP 202 + LRO stalling? |
| 36 | │ ├── YES → Polling issue. See §3 LRO Optimization |
| 37 | │ └── NO → Continue |
| 38 | ├── Large result sets slow? |
| 39 | │ ├── YES → Pagination. See §4 Pagination Tuning |
| 40 | │ └── NO → Continue |
| 41 | ├── Token acquisition slow? |
| 42 | │ ├── YES → Auth latency. See §5 Token Performance |
| 43 | │ └── NO → General latency. See §6 Baseline Benchmarking |
| 44 | ``` |
| 45 | |
| 46 | --- |
| 47 | |
| 48 | ## §1 Throttling Diagnosis (HTTP 429) |
| 49 | |
| 50 | Fabric throttles per-user, per-API within a time window. When exceeded, the API returns HTTP 429 with a `Retry-After` header (in seconds). |
| 51 | |
| 52 | **Diagnosis Steps:** |
| 53 | |
| 54 | 1. Run the [throttle diagnostic script](./scripts/Test-FabricApiThrottle.ps1) to measure your current request rate against throttle limits |
| 55 | 2. Capture `Retry-After` header values to understand cooldown periods |
| 56 | 3. Review call patterns for burst behavior vs. steady-state |
| 57 | |
| 58 | **Resolution Patterns:** |
| 59 | |
| 60 | | Pattern | Description | |
| 61 | |---------|-------------| |
| 62 | | Exponential backoff | Respect `Retry-After`, then add jitter to avoid thundering herd | |
| 63 | | Request batching | Group related calls to reduce total API invocations | |
| 64 | | Caller isolation | Use separate service principals for independent workloads | |
| 65 | | Rate limiter | Implement a client-side token bucket before sending requests | |
| 66 | |
| 67 | **Key Facts:** |
| 68 | |
| 69 | - Every Fabric admin and core public API call is throttled |
| 70 | - Throttle window and limits are per-user, per-API (not published explicitly) |
| 71 | - The `Retry-After` value is in seconds (commonly 30-60s) |
| 72 | |
| 73 | See [throttling-deep-dive.md](./references/throttling-deep-dive.md) for implementation patterns. |
| 74 | |
| 75 | --- |
| 76 | |
| 77 | ## §2 Capacity Rate Limits (HTTP 430) |
| 78 | |
| 79 | Spark jobs and compute-bound operations have a separate throttle tied to the Fabric capacity SKU. When the max queue limit is reached, new jobs return HTTP 430. |
| 80 | |
| 81 | **Capacity Queue Limits:** |
| 82 | |
| 83 | | SKU | Queue Limit | |
| 84 | |-----|-------------| |
| 85 | | F2 / F4 | 4 | |
| 86 | | F8 | 8 | |
| 87 | | F16 | 16 | |
| 88 | | F32 | 32 | |
| 89 | | F64 (P1) | 64 | |
| 90 | | F128 (P2) | 128 | |
| 91 | | F256 (P3) | 256 | |
| 92 | | F512 (P4) | 512 | |
| 93 | | F1024 | 1024 | |
| 94 | | F2048 | 2048 | |
| 95 | | Trial | Not supported | |
| 96 | |
| 97 | **Resolution:** |
| 98 | |
| 99 | 1. Cancel active Spark jobs via the Monitoring Hub |
| 100 | 2. Upgrade to a larger capacity SKU |
| 101 | 3. Enable optimistic job admission for higher concurrency |
| 102 | 4. Implement client-side queue management before submitting jobs |
| 103 | |
| 104 | --- |
| 105 | |
| 106 | ## §3 Long Running Operation (LRO) Optimization |
| 107 | |
| 108 | Many Fabric APIs return HTTP 202 Accepted with three critical headers: |
| 109 | |
| 110 | - `Location` — polling URL (Get Operation State endpoint) |
| 111 | - `x-ms-operation-id` — operation GUID for constructing polling URLs |
| 112 | - `Retry-After` — seconds to wait before first poll |
| 113 | |
| 114 | **Common Performance Issues:** |
| 115 | |
| 116 | | Issue | Symptom | Fix | |
| 117 | |-------|---------|-----| |
| 118 | | Aggressive polling | Hundreds of GET calls, wastes quota | Honor `Retry-After`, use exponential backoff | |
| 119 | | Ignoring Location header | Building URLs manually, missing result endpoint | Use Location header directly; it transitions from State to Result when complete | |
| 120 | | Not checking for result | Polling succeeds but result never fetched | After `Succeeded` status, call Get Operation Result | |
| 121 | | Missing failure handling | Stuck in inf |