-
Notifications
You must be signed in to change notification settings - Fork 231
feat(queries): add FinOps KPI query catalog #2166
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
8948b1a
feat(queries): add FinOps KPI query catalog
a1f7008
fix(queries): remove markdown trailing whitespace
32b71cf
fix(queries): address catalog review comments
94d31b9
docs(queries): remove duplicate framework reference
49d8bc4
fix(queries): apply review followups across catalog
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| // ============================================================================ | ||
| // Query: Azure OpenAI Cost by Application | ||
| // Description: | ||
| // Breaks down Azure OpenAI costs by application, cost center, team, and environment tags. | ||
| // Useful for AI workload showback, chargeback, and unit economics analysis. | ||
| // Author: FinOps Toolkit Team | ||
| // Parameters: | ||
| // startDate: Start date for the reporting period (e.g., startofmonth(ago(30d))) | ||
| // endDate: End date for the reporting period (e.g., startofmonth(now())) | ||
| // Output: | ||
| // Each row represents a tagged Azure OpenAI cost grouping with token count and cost metrics. | ||
| // Usage: | ||
| // Use this query to allocate Azure OpenAI usage and cost to applications, teams, and environments. | ||
| // Last Updated: 2026-05-26 | ||
| // ============================================================================ | ||
|
|
||
| let startDate = startofmonth(ago(30d)); | ||
| let endDate = startofmonth(now()); | ||
| Costs() | ||
| | where ChargePeriodStart >= startDate and ChargePeriodStart < endDate | ||
| | where x_SkuMeterSubcategory has "OpenAI" | ||
| | extend Application = tostring(Tags["application"]) | ||
| | extend CostCenter = case( | ||
| isnotempty(tostring(Tags["cost-center"])), tostring(Tags["cost-center"]), | ||
| isnotempty(tostring(Tags["CostCenter"])), tostring(Tags["CostCenter"]), | ||
| "") | ||
| | extend Environment = tostring(Tags["environment"]) | ||
| | extend Team = tostring(Tags["team"]) | ||
| | summarize | ||
| TokenCount = sum(ConsumedQuantity), | ||
| EffectiveCost = sum(EffectiveCost), | ||
| BilledCost = sum(BilledCost) | ||
| by BillingCurrency, Application, CostCenter, Team, Environment, ResourceName, x_SkuMeterSubcategory | ||
| | extend CostPer1KTokens = iff(TokenCount == 0, 0.0, EffectiveCost / TokenCount * 1000) | ||
| | order by EffectiveCost desc | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| // ============================================================================ | ||
| // Query: Azure OpenAI Daily Cost and Token Trend | ||
| // Description: | ||
| // Returns daily Azure OpenAI token consumption and effective cost. | ||
| // Useful for AI workload anomaly detection, forecasting, and trend reporting. | ||
| // Author: FinOps Toolkit Team | ||
| // Parameters: | ||
| // startDate: Start date for the reporting period (e.g., ago(30d)) | ||
| // endDate: End date for the reporting period (e.g., now()) | ||
| // Output: | ||
| // Each row represents one day with token count, cost, and cost per 1K tokens. | ||
| // Usage: | ||
| // Use this query to monitor AI workload consumption trends and detect daily cost spikes. | ||
| // Last Updated: 2026-05-26 | ||
| // ============================================================================ | ||
|
|
||
| let startDate = ago(30d); | ||
| let endDate = now(); | ||
| Costs() | ||
| | where ChargePeriodStart >= startDate and ChargePeriodStart < endDate | ||
| | where x_SkuMeterSubcategory has "OpenAI" | ||
| | summarize | ||
| DailyTokens = sum(ConsumedQuantity), | ||
| DailyCost = sum(EffectiveCost) | ||
| by Day = bin(ChargePeriodStart, 1d), BillingCurrency | ||
| | extend CostPer1KTokens = iff(DailyTokens == 0, 0.0, DailyCost / DailyTokens * 1000) | ||
| | order by Day asc, BillingCurrency asc |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| // ============================================================================ | ||
| // Query: Azure OpenAI Model Cost Comparison | ||
| // Description: | ||
| // Compares token volume, effective cost, list cost, and discount percentage by model. | ||
| // Useful for AI model cost efficiency analysis and rate optimization. | ||
| // Author: FinOps Toolkit Team | ||
| // Parameters: | ||
| // startDate: Start date for the reporting period (e.g., startofmonth(ago(30d))) | ||
| // endDate: End date for the reporting period (e.g., startofmonth(now())) | ||
| // Output: | ||
| // Each row represents one Azure OpenAI model or SKU description with cost per 1K tokens. | ||
| // Usage: | ||
| // Use this query to compare model economics and identify where model or commitment changes may reduce AI spend. | ||
| // Last Updated: 2026-05-26 | ||
| // ============================================================================ | ||
|
|
||
| let startDate = startofmonth(ago(30d)); | ||
| let endDate = startofmonth(now()); | ||
| Costs() | ||
| | where ChargePeriodStart >= startDate and ChargePeriodStart < endDate | ||
| | where x_SkuMeterSubcategory has "OpenAI" | ||
| | extend Model = x_SkuDescription | ||
| | summarize | ||
| TokenCount = sum(ConsumedQuantity), | ||
| EffectiveCost = sum(EffectiveCost), | ||
| ListCost = sum(ListCost) | ||
| by BillingCurrency, Model | ||
| | extend CostPer1KTokens = iff(TokenCount == 0, 0.0, EffectiveCost / TokenCount * 1000) | ||
| | extend ListPer1KTokens = iff(TokenCount == 0, 0.0, ListCost / TokenCount * 1000) | ||
| | extend DiscountPercent = iff(ListCost == 0, 0.0, (ListCost - EffectiveCost) / ListCost * 100) | ||
| | order by EffectiveCost desc | ||
|
MSBrett marked this conversation as resolved.
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| // ============================================================================ | ||
| // Query: Azure OpenAI Token Usage Breakdown | ||
| // Description: | ||
| // Breaks Azure OpenAI token consumption down by model version and input/output direction. | ||
| // Calculates effective unit cost per token and cost per 1K tokens. | ||
| // Author: FinOps Toolkit Team | ||
| // Parameters: | ||
| // startDate: Start date for the reporting period (e.g., startofmonth(ago(30d))) | ||
| // endDate: End date for the reporting period (e.g., startofmonth(now())) | ||
| // Output: | ||
| // Each row represents one model and direction with token count and cost metrics. | ||
| // Usage: | ||
| // Use this query to analyze AI workload unit economics, token direction mix, and model cost efficiency. | ||
| // Last Updated: 2026-05-26 | ||
| // ============================================================================ | ||
|
|
||
| let startDate = startofmonth(ago(30d)); | ||
| let endDate = startofmonth(now()); | ||
| Costs() | ||
| | where ChargePeriodStart >= startDate and ChargePeriodStart < endDate | ||
| | where x_SkuMeterSubcategory has "OpenAI" | ||
| | extend Model = x_SkuDescription | ||
| | extend Direction = case( | ||
| Model contains "Input", "Input", | ||
| Model contains "Output", "Output", | ||
| "Other") | ||
| | summarize | ||
| TokenCount = sum(ConsumedQuantity), | ||
| EffectiveCost = sum(EffectiveCost), | ||
| BilledCost = sum(BilledCost), | ||
| ListCost = sum(ListCost) | ||
| by BillingCurrency, Model, Direction | ||
| | extend UnitCostPerToken = iff(TokenCount == 0, 0.0, EffectiveCost / TokenCount) | ||
| | extend CostPer1KTokens = UnitCostPerToken * 1000 | ||
| | order by EffectiveCost desc | ||
|
MSBrett marked this conversation as resolved.
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| // ============================================================================ | ||
| // Query: Allocation Accuracy Index | ||
| // Description: | ||
| // Calculates the percentage of total effective cost that is directly attributed using a | ||
| // three-signal heuristic: allocation rule, cost center, or ownership-tag evidence. | ||
| // KPI: Allocation Accuracy Index (AAI) | ||
| // Formula: Allocation Accuracy Index (AAI) = (Directly Attributed Costs / Total Infrastructure Costs) × 100 | ||
| // Author: FinOps toolkit | ||
| // Parameters: | ||
| // startDate: datetime; start date for the reporting period (default: startofmonth(ago(30d))) | ||
| // endDate: datetime; end date for the reporting period (default: startofmonth(now())) | ||
| // allocationEvidenceTagKeys: dynamic; tag keys treated as ownership evidence (default: dynamic(['cost-center','team','owner','application','product'])) | ||
| // Output: | ||
| // Each row represents one BillingCurrency and returns DirectlyAttributedCost, TotalEffectiveCost, | ||
| // and AAI for Hub-visible CSP costs in the reporting window. | ||
| // Usage: | ||
| // Use this query to measure how much effective cost is directly attributable within FinOps Hub. | ||
| // Scope Notes: Hub-only AAI. Does not include on-prem, SaaS, or other infrastructure outside Hub schema. | ||
| // Last Tested: 2026-05-28 against a FinOps Hub ADX cluster (1,366,763 cost rows in 2026-04 window). UAT result: PASS — 1 row returned | ||
| // ========================================================================= | ||
| let startDate = startofmonth(ago(30d)); | ||
| let endDate = startofmonth(now()); | ||
| let allocationEvidenceTagKeys = dynamic(['cost-center','team','owner','application','product']); | ||
| Costs() | ||
| | where ChargePeriodStart >= startDate and ChargePeriodStart < endDate | ||
| | where not(ChargeCategory == 'Purchase' and isnotempty(CommitmentDiscountCategory)) | ||
| | extend tmp_TagKeys = coalesce(bag_keys(Tags), dynamic([])) | ||
| | extend tmp_IsAttributed = isnotempty(x_CostAllocationRuleName) | ||
| or isnotempty(x_CostCenter) | ||
| or array_length(set_intersect(tmp_TagKeys, allocationEvidenceTagKeys)) > 0 | ||
| | summarize | ||
|
MSBrett marked this conversation as resolved.
|
||
| DirectlyAttributedCost = todouble(sumif(EffectiveCost, tmp_IsAttributed)), | ||
| TotalEffectiveCost = todouble(sum(EffectiveCost)) | ||
| by BillingCurrency | ||
| | extend AAI = iff(TotalEffectiveCost == 0, 0.0, DirectlyAttributedCost / TotalEffectiveCost * 100.0) | ||
| | project BillingCurrency, DirectlyAttributedCost, TotalEffectiveCost, AAI | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,53 @@ | ||
| // ============================================================================ | ||
| // Query: Anomaly Detection Rate | ||
| // Description: | ||
| // Calculates the percentage of effective spend attributable to anomaly-flagged days. | ||
| // Builds daily cost series per service category and billing currency, then applies time-series anomaly detection. | ||
| // KPI: Anomaly Detection Rate | ||
| // Formula: Total Cost of Anomaly Spikes / Total Spend = Anomaly Cost % | ||
| // Author: FinOps toolkit | ||
| // Parameters: | ||
| // startDate: datetime; Start date for the reporting period (default: startofmonth(ago(30d))) | ||
| // endDate: datetime; End date for the reporting period (default: startofmonth(now())) | ||
| // sensitivity: real; Anomaly detection sensitivity for series_decompose_anomalies() (default: 1.5) | ||
| // Output: | ||
| // Each row returns a BillingCurrency and ServiceCategory pair (plus an Overall rollup row) with AnomalyCost, TotalCost, and AnomalyRatePercent as double values. | ||
| // Usage: | ||
| // Use this query to quantify how much effective spend falls on anomaly-flagged days by service category and by billing currency. | ||
| // Scope Notes: | ||
| // Treats both positive spikes and negative drops as anomalies (AnomalyFlags != 0); the Overall row is per BillingCurrency only. | ||
| // Missing days are zero-filled via make-series default=0.0, and commitment purchase rows are excluded to avoid amortization double-counting. | ||
| // Last Tested: 2026-05-28 against a FinOps Hub ADX cluster (1,366,763 cost rows in 2026-04 window). UAT result: PASS — 13 rows returned (per service category) | ||
| // ========================================================================= | ||
| let startDate = startofmonth(ago(30d)); | ||
| let endDate = startofmonth(now()); | ||
| let sensitivity = 1.5; | ||
| let expanded = materialize( | ||
| Costs() | ||
| | where ChargePeriodStart >= startDate and ChargePeriodStart < endDate | ||
| | where not(ChargeCategory == 'Purchase' and isnotempty(CommitmentDiscountCategory)) | ||
| | summarize DailyCost = sum(todouble(EffectiveCost)) | ||
| by bin(ChargePeriodStart, 1d), ServiceCategory, BillingCurrency | ||
| | make-series CostSeries = sum(DailyCost) default=0.0 | ||
| on ChargePeriodStart from startDate to endDate step 1d | ||
| by ServiceCategory, BillingCurrency | ||
| | extend AnomalyFlags = series_decompose_anomalies(CostSeries, sensitivity) | ||
| | mv-expand CostSeries to typeof(double), AnomalyFlags to typeof(int) | ||
| ); | ||
| let perCategory = | ||
| expanded | ||
| | summarize | ||
| AnomalyCost = todouble(sumif(CostSeries, AnomalyFlags != 0)), | ||
| TotalCost = todouble(sum(CostSeries)) | ||
| by BillingCurrency, ServiceCategory | ||
| | extend AnomalyRatePercent = todouble(iff(TotalCost == 0.0, 0.0, AnomalyCost / TotalCost * 100.0)); | ||
| let overall = | ||
| expanded | ||
| | summarize | ||
| AnomalyCost = todouble(sumif(CostSeries, AnomalyFlags != 0)), | ||
| TotalCost = todouble(sum(CostSeries)) | ||
| by BillingCurrency | ||
| | extend ServiceCategory = 'Overall' | ||
| | extend AnomalyRatePercent = todouble(iff(TotalCost == 0.0, 0.0, AnomalyCost / TotalCost * 100.0)); | ||
| union perCategory, overall | ||
| | project BillingCurrency, ServiceCategory, AnomalyCost, TotalCost, AnomalyRatePercent |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,65 @@ | ||
| // ============================================================================ | ||
| // Query: Total Unpredicted Variance of Spend | ||
| // Description: | ||
| // Calculates the net unpredicted variance between actual effective cost and the anomaly baseline | ||
| // for anomaly-flagged daily buckets by service category and billing currency. | ||
| // KPI: Total Unpredicted Variance of Spend | ||
| // Formula: Total effective cost associated with all anomaly events detected less the predicted spend of the services related to the identified anomalies. | ||
| // Author: FinOps toolkit | ||
| // Parameters: | ||
| // startDate: datetime; start of the reporting period (default: startofmonth(ago(12 * 30d))) | ||
| // endDate: datetime; end of the reporting period (default: now()) | ||
| // anomalyThreshold: real; anomaly detection sensitivity threshold (default: 1.5) | ||
| // Output: | ||
| // Each row returns BillingCurrency, ServiceCategory, AnomalyEventCount, UnpredictedVarianceSigned, | ||
| // and UnpredictedVarianceAbs for anomaly-detected daily buckets; "(All Services)" rows provide | ||
| // per-currency totals across all service categories. | ||
| // Usage: | ||
| // Use this query to quantify net anomalous overspend or underspend by service category and currency. | ||
| // Scope Notes: | ||
| // Per-group anomaly detection runs independently per (ServiceCategory, BillingCurrency), and groups | ||
| // with sparse history are filtered when no anomaly baseline is produced. Each BillingCurrency is | ||
| // reported separately and must not be summed across currencies without FX conversion. The default | ||
| // 12-month window supports STL seasonality decomposition, and UnpredictedVarianceAbs is defined as | ||
| // abs(sum(actual - baseline)) rather than sum(abs(actual - baseline)). | ||
| // Last Tested: 2026-05-28 against a FinOps Hub ADX cluster (1,366,763 cost rows in 2026-04 window). UAT result: PASS — 13 rows returned (per service category) | ||
| // ========================================================================= | ||
| let startDate = startofmonth(ago(12 * 30d)); | ||
| let endDate = now(); | ||
| let anomalyThreshold = 1.5; | ||
| let anomalyBuckets = | ||
| Costs() | ||
| | where ChargePeriodStart >= startDate and ChargePeriodStart < endDate | ||
| | where not(ChargeCategory == 'Purchase' and isnotempty(CommitmentDiscountCategory)) | ||
| | summarize DailyCost = sum(EffectiveCost) by ServiceCategory, BillingCurrency, bin(ChargePeriodStart, 1d) | ||
| | make-series CostSeries = sum(DailyCost) default=0.0 on ChargePeriodStart from startDate to endDate step 1d by ServiceCategory, BillingCurrency | ||
| | extend (ad_flag, ad_score, ad_baseline) = series_decompose_anomalies(CostSeries, anomalyThreshold) | ||
| | mv-expand ChargePeriodStart to typeof(datetime), CostSeries to typeof(real), ad_flag to typeof(real), ad_score to typeof(real), ad_baseline to typeof(real) | ||
| | extend ad_flag = toint(ad_flag), CostSeries = toreal(CostSeries), ad_score = toreal(ad_score), ad_baseline = toreal(ad_baseline) | ||
| | where isnotnull(ad_baseline) | ||
| | where ad_flag != 0 | ||
| | extend Variance = todouble(CostSeries) - todouble(ad_baseline); | ||
| union | ||
| ( | ||
| anomalyBuckets | ||
| | summarize | ||
| AnomalyEventCount = count(), | ||
| UnpredictedVarianceSigned = todouble(sum(Variance)), | ||
| UnpredictedVarianceAbs = todouble(abs(sum(Variance))) | ||
| by BillingCurrency, ServiceCategory | ||
| ), | ||
| ( | ||
| anomalyBuckets | ||
| | summarize | ||
| AnomalyEventCount = count(), | ||
| UnpredictedVarianceSigned = todouble(sum(Variance)), | ||
| UnpredictedVarianceAbs = todouble(abs(sum(Variance))) | ||
| by BillingCurrency | ||
| | extend ServiceCategory = "(All Services)" | ||
| ) | ||
| | project | ||
| BillingCurrency, | ||
| ServiceCategory, | ||
| AnomalyEventCount, | ||
| UnpredictedVarianceSigned = todouble(UnpredictedVarianceSigned), | ||
| UnpredictedVarianceAbs = todouble(UnpredictedVarianceAbs) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.