fabric-udf-perf-remediate — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited fabric-udf-perf-remediate (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Systematic guide for diagnosing and resolving performance issues with Fabric User Data Functions (UDFs). Covers cold starts, execution timeouts, capacity consumption, connection bottlenecks, and Python code optimization.
| Limit | Value | Impact |
|---|---|---|
| Request payload | 4 MB | All input parameters combined |
| Execution timeout | 240 seconds | Maximum function runtime |
| Response size | 30 MB | Maximum return value size |
| Log retention | 30 days | Historical invocation log window |
| Private library max | 28.6 MB | Per .whl file upload |
| Test session timeout | 15 minutes | Idle timeout in Develop mode |
| Daily log ingestion | 250 MB | Logs may be sampled beyond this |
| Python version (Run) | 3.11 | Published functions runtime |
| Python version (Test) | 3.12 | Develop mode test runtime |
Determine which category your issue falls into:
| Symptom | Likely Root Cause | Go To |
|---|---|---|
| First invocation slow, subsequent fast | Cold start / initialization | Step 2 |
| All invocations consistently slow | Code inefficiency or data volume | Step 3 |
| Intermittent timeouts | Connection issues or capacity throttling | Step 4 |
| Response too large error | Unbounded query results | Step 5 |
| High CU consumption in Metrics app | Excessive execution frequency or duration | Step 6 |
| Function fails with import errors | Library loading overhead | Step 7 |
Fabric User Data Functions run in a serverless environment. The first invocation after a period of inactivity incurs initialization overhead.
Check historical logs for the pattern:
Mitigations:
.whl adds init time)definition.jsonFor consistently slow functions, instrument your code with timing:
import logging
import time
@udf.function()
def my_function(param: str) -> str:
start = time.perf_counter()
# Phase 1: Data retrieval
t1 = time.perf_counter()
data = fetch_data(param)
logging.info(f"Data retrieval: {time.perf_counter() - t1:.3f}s")
# Phase 2: Processing
t2 = time.perf_counter()
result = process(data)
logging.info(f"Processing: {time.perf_counter() - t2:.3f}s")
logging.info(f"Total execution: {time.perf_counter() - start:.3f}s")
return resultReview logs in the Invocation details pane to identify the slowest phase.
Common bottlenecks and fixes:
See performance-optimization.md for detailed code patterns.
Connection errors to Fabric data sources:
Capacity throttling indicators:
TooManyRequestsForCapacityTimeout approaching 240s:
logging.warning() to flag operations exceeding thresholdsThe 30 MB response limit triggers when functions return large datasets unbounded.
Diagnostic approach:
import sys
import json
import logging
@udf.function()
def my_query_function() -> list:
results = execute_query()
size_bytes = sys.getsizeof(json.dumps(results))
logging.info(f"Response size estimate: {size_bytes / (1024*1024):.2f} MB")
if size_bytes > 25_000_000: # 25 MB warning threshold
logging.warning("Response approaching 30 MB limit")
return resultsMitigations:
UDF operations reported in the Fabric Capacity Metrics app:
| Operation | Type | Trigger |
|---|---|---|
| User Data Functions Execution | Interactive | Function invoked by portal, Fabric item, or external app |
| User Data Functions Portal Test | Interactive | Testing in Develop mode (minimum 15-min session) |
| User Data Functions Static Storage | Background | Metadata stored in OneLake (always-on cost) |
| User Data Functions Static Storage Read | Background | Metadata read after inactivity period |
| User Data Functions Static Storage Write | Background | Every publish operation |
Cost reduction strategies:
Run the capacity-analysis.ps1 script to generate a capacity usage summary.
Heavy or numerous libraries increase initialization time and can cause import errors.
Best practices:
definition.jsonhttpx over requests if async needed).whl files must be under 28.6 MB each# Instead of top-level import
# import heavy_library
@udf.function()
def my_function() -> str:
import heavy_library # Lazy import - only loads when function is called
return heavy_library.process()Use structured logging to make performance data queryable in historical logs:
import logging
# Log at key decision points
logging.info(f"PERF|function_name|phase|{duration_ms}ms|{record_count} rows")
# Use appropriate levels
logging.warning(f"PERF|slow_query|{duration_ms}ms exceeds 5000ms threshold")
logging.error(f"PERF|timeout_risk|{duration_ms}ms approaching 240s limit")See the logging template for a reusable instrumented function pattern.
Function is slow or failing
├── First call only? → Cold start (Step 2)
├── All calls slow?
│ ├── Data source query slow? → Optimize query (Step 3)
│ ├── Processing slow? → Profile code (Step 3)
│ └── Response too large? → Add pagination (Step 5)
├── Intermittent failures?
│ ├── HTTP 430 errors? → Capacity throttling (Step 4)
│ ├── Connection timeout? → Data source issues (Step 4)
│ └── Import errors? → Library problems (Step 7)
└── High CU bill?
└── Analyze metrics app (Step 6)User Data Functions are not available in all Fabric regions. The Test capability in Develop mode is additionally unavailable in Brazil South, Israel Central, and Mexico Central. If your tenant region is unsupported, create a Capacity in a supported region.
Check current region availability at Fabric region availability.
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.