Toggle dark/light theme
← Back to catalog
Architecture diagram
Expand

Fabric Platform Monitoring - Capacity Events

Overview

Monitor your Fabric capacity utilization in real-time using Capacity Events. Ingest capacity telemetry into an Eventhouse via Eventstream and visualize resource consumption trends on live KQL dashboards for proactive management.

Class
Core
Type
Accelerator
Difficulty
Beginner
Deploy Time
~2 min
Complete Time
~5 min

Workloads

Real-Time IntelligenceData Factory

Fabric Items Deployed

  • Notebook
  • Eventhouse
  • Eventstream
  • KQL Database
  • Real-Time Dashboard
  • Data Pipeline

Scenarios

Monitoring

This jumpstart deploys a Fabric capacity observability stack into your workspace β€” a one-cell setup notebook that subscribes every capacity you administer to the Fabric Capacity Events feed, an Eventstream that funnels those events into an Eventhouse-backed KQL database with three pre-built parsing functions and update policies, and a multi-page real-time KQL Dashboard that visualizes capacity utilization, throttling thresholds, overage, workload mix, and capacity state changes β€” all installed with one call.

⏱️ Deploy time: ~2 minutes. Plan another ~5 minutes to run the setup notebook, watch the first events land, and open the dashboard.

What Gets Deployed

Item Type Role
Capacity Events Update Eventstream Notebook One-cell bootstrap. Pip-installs fabric-deployment-tool, then calls FabDeploymentTool().update_capcity_events_eventstream(workspace_name) to subscribe every Fabric capacity where the executing user is an Administrator to the CapacityEvents Eventstream's Capacity CustomEndpoint.
Capacity Events Update Eventstream DataPipeline Wraps the setup notebook in a single TridentNotebook activity named Update Eventstream. Ships with a disabled daily schedule at 01:00 UTC β€” enable it if you want the capacity subscription to refresh automatically as admin assignments change.
CapacityEvents Eventstream Source: a CustomEndpoint named Capacity that the setup notebook subscribes capacities to. Two destinations: CustomOutput (a CustomEndpoint for downstream consumers) and Eventhouse via DirectIngestion into the CapacityEventsRaw table using the CapacityEventsRaw_mapping JSON mapping. Stream properties: eventThroughputLevel: Low, retentionTimeInDays: 1 β€” sized for steady-state low-volume capacity events.
Fabric Platform Monitoring Eventhouse Container for the KQL database below. The Eventhouse itself ships with default properties (EventhouseProperties.json is {}); per-database OneLake caching/storage on Capacity Utilization is P365000D (effectively unbounded) β€” actual aging is governed by the per-table retention policies described below.
Capacity Utilization KQLDatabase All capacity telemetry lives here. Raw events land in CapacityEventsRaw; three update policies fan them out into typed tables. See "How It Works" below for the schema.
Capacity Monitoring KQLDashboard Two-page real-time KQL Dashboard (auto-refresh every 30s) β€” Capacity Summary for the fleet-wide overview and Capacity Details for per-capacity drill-through.

How It Works

Setup β€” subscribing your capacities to the Eventstream

The setup notebook is the entry point. It runs two cells:

  1. %pip install fabric-deployment-tool --quiet.
  2. Resolves the current workspace name via sempy.fabric.get_notebook_workspace_id() and fabric.list_workspaces(...), then calls FabDeploymentTool().update_capcity_events_eventstream(workspace_name).

That single call discovers every Fabric capacity where the executing user is a Capacity Administrator, then reconfigures the CapacityEvents Eventstream's Capacity CustomEndpoint to subscribe to events for exactly that set β€” adding new capacities and removing any the user no longer administers.

Scheduling refresh with the pipeline

Capacity Events Update Eventstream (DataPipeline) wraps the notebook in a single TridentNotebook activity called Update Eventstream. The shipped .schedules config defines a daily 01:00 UTC trigger that is disabled by default β€” enable it once you've decided which identity should own ongoing capacity discovery. Once enabled, every admin reassignment is picked up within 24 hours without any manual edit.

Ingest β€” Eventstream to Eventhouse

CapacityEvents has:

  • Source β€” one CustomEndpoint named Capacity. The Fabric Capacity Events service emits CloudEvents (Microsoft.Fabric.Capacity.Summary, Microsoft.Fabric.Capacity.State) for each subscribed capacity.
  • Destinations β€” CustomOutput (a CustomEndpoint, in case you want to fan out to another consumer) and Eventhouse with dataIngestionMode: DirectIngestion, writing to CapacityEventsRaw using the CapacityEventsRaw_mapping JSON mapping.

Every capacity event lands in CapacityEventsRaw within seconds, durably stored and KQL-queryable from the Capacity Utilization database.

Parse β€” raw events become typed, queryable tables

Capacity Utilization's DatabaseSchema.kql defines four tables and three parsing functions. The raw table has a short, hot retention; the parsed tables are tuned for two years of analytics.

Table What's in it Retention Hot cache
CapacityEventsRaw The raw CloudEvent envelope β€” specversion, source, time, id, subject, dataschemaversion, type, and a dynamic data payload. Folder Raw. 1 hour 1 day
CapacitySummary Typed projection of Microsoft.Fabric.Capacity.Summary events β€” base/timepoint CU, CU-ms and CU-seconds, interactive/background utilization, preview utilization, overage CU-ms (total / added / burndown / billing limit), throttling thresholds (interactive delay, interactive reject, background reject), and the capacityUnitUtilizationBreakdown payload. 730 days 90 days
CapacityState Typed projection of Microsoft.Fabric.Capacity.State events β€” transitionTime, capacityState, stateChangeReason. 730 days 90 days
CapacityWorkloadSummary mv-expanded workload-level breakdown extracted from the capacityUnitUtilizationBreakdown payload on summary events β€” workloadKind, interactiveCU, backgroundCU, interactivePreviewCU, backgroundPreviewCU per workload. (uses database default) (uses database default)

The three parse functions live in the UpdatePolicyFunctions folder and are bound as transactional update policies on the three destination tables (CapacitySummary, CapacityState, CapacityWorkloadSummary), each with CapacityEventsRaw as the source:

  • parse_CapacityEventsSummary() β€” filters type == "Microsoft.Fabric.Capacity.Summary", projects typed columns, and derives timepointCapacityUnits = baseCapacityUnits * 30 and capacityUnitSecond = capacityUnitMs / 1000.0.
  • parse_CapacityEventsState() β€” filters type == "Microsoft.Fabric.Capacity.State" and projects the state-transition fields.
  • parse_CapacityEventsWorkloadSummary() β€” filters summary events that have a non-empty capacityUnitUtilizationBreakdown, then mv-expands the per-workload utilization rows.

The result: anything you write into CapacityEventsRaw from the Eventstream is automatically and transactionally fanned out into the three typed tables β€” no orchestration needed.

Consume β€” the Capacity Monitoring dashboard

Capacity Monitoring is a two-page KQL Dashboard with auto-refresh every 30 seconds, sourced from the Capacity Utilization database.

  • Capacity Summary β€” fleet-wide view. Tiles: Capacities (count card), Capacity Overview (table with drill-through to per-capacity pages), and Capacity State.
  • Capacity Details β€” per-capacity drill-through. Tiles: Total CU in Time Range by Utilization Type, Utilization Type Distribution, Capacity Utilization, Overage, % Capacity Utilization (Current), Throttling Threshold, Capacity State (also appears here), Workspaces With Activity, Workload Breakdown, % Interactive Delay Threshold, % Interactive Reject Threshold, % Background Reject Threshold, and NΒΊ Workloads.

The dashboard exposes parameters for Capacity Sku, Capacity, Workspace Name Search, Workspace Name Exact (Limit 1000), Item, and Time range, with Capacity Id flowing through cross-filters and drill-through pairs.

Try It β€” A Five-Minute Walkthrough

  1. Install β€” jumpstart.install("fpm-capacity-events") and wait for the ~2-minute deploy.
  2. Bootstrap β€” open Capacity Events Update Eventstream (the notebook) and run all cells. Make sure you're signed in as a Capacity Administrator on at least one capacity, otherwise the subscription will be empty.
  3. Wait for ingestion β€” within a minute or two, CapacityEventsRaw should start populating. Open Capacity Utilization and run CapacityEventsRaw | take 10 and CapacitySummary | take 10 to confirm raw events and typed projections.
  4. Open the dashboard β€” launch Capacity Monitoring, land on the Capacity Summary page, and pick a capacity. Click into a row to drill through to Capacity Details.
  5. Schedule the refresh (optional) β€” open the Capacity Events Update Eventstream pipeline and enable the daily 01:00 UTC schedule so the capacity subscription tracks admin changes automatically.

Extending the Accelerator

Extension How
Track admin reassignments automatically Enable the disabled daily schedule on Capacity Events Update Eventstream (pipeline). The pipeline executes the notebook under the pipeline owner's identity, so make sure that identity is a Capacity Administrator on the capacities you want to monitor.
Fan out to another consumer The Eventstream already exposes a CustomOutput (CustomEndpoint) destination β€” point Reflex, Spark structured streaming, or any other consumer at that endpoint without touching the Eventhouse path.
Alert on capacity throttling Add an Activator (Reflex) on a KQL query against CapacitySummary that fires when utilizationInteractive, utilizationBackground, or processedOverageCapacityUnitsMs cross a threshold β€” or against CapacityState for state-change notifications.
Re-parse history The raw table only retains 1 hour by default. To re-parse historical events lower the SoftDeletePeriod on CapacityEventsRaw before ingestion, or replay from the CustomOutput endpoint into a side table.
Add per-workload chargeback views Build a Power BI semantic model or KQL queryset over CapacityWorkloadSummary β€” it already breaks down interactiveCU / backgroundCU per workloadKind, which is the unit of chargeback most teams want.
Increase event throughput The Eventstream is provisioned with eventThroughputLevel: Low. If you subscribe many capacities or emit higher-volume custom events, bump it via the Eventstream settings.

Cost Notes

The setup notebook and pipeline cost almost nothing β€” they only run when triggered, and the pipeline schedule ships disabled. The KQL Dashboard's auto-refresh is the second cost item to watch: every 30 seconds it re-runs every visible tile's KQL against the database.

Requirements

  • A Microsoft Fabric workspace with at least F2 capacity (Eventhouse + Real-Time Dashboard need it).
  • The user running the setup notebook (and the identity owning the pipeline, if scheduled) must be a Capacity Administrator on every capacity you want to monitor β€” there is no manual capacity list.
  • Permissions to create Eventstream, Eventhouse, KQL Database, KQL Dashboard, Notebook, and Data Pipeline items.
  • Outbound internet from the notebook session β€” it pip-installs fabric-deployment-tool on each run.

Resources