Repository navigation
fix(finops-framework): correct 1000x overstated cost and rescale the demo quotas - #399
Merged
Alex Vieira (vieiraae) merged 2 commits intoSep 16, 2026
Conversation
…tion
The Azure Retail Prices API returns Foundry Models token meters with
`unitOfMeasure` of `1K`, i.e. `retailPrice` is already the price per 1000
tokens (for example `gpt 4.1 mini Inp glbl` in swedencentral returns
`retailPrice: 0.0004`).
The notebook multiplied that value by 1000 before writing it to the
`PRICING_CL` custom table, while every cost query consuming the table
computes:
| extend InputCost = PromptTokens * InputTokensPrice
| extend OutputCost = CompletionTokens * OutputTokensPrice
| extend TotalCost = (InputCost + OutputCost) / 1000
Those queries already divide by 1000, so they expect a per-1K price. The
extra multiplication made every reported cost 1000x too high: 1M input
tokens on gpt-4.1-mini was reported as 400 USD instead of 0.40 USD.
This affects the cost analysis workbook, the dashboard, and the
`alert-suspend-sub` / `alert-activate-sub` scheduled query rules, which
means cost quotas could suspend an APIM subscription almost immediately.
Store `retailPrice` as returned. The consuming KQL is left unchanged
since it is already consistent with a per-1K price. The display-only
pricing table keeps its multiplication, and its column is renamed to
make the unit explicit. The markdown note that described the incorrect
scaling is corrected as well.
…ices The `costQuota` values were calibrated against prices that were overstated by 1000x, so they were effectively expressed in units of a thousand tokens' worth of cost. With the prices corrected in the previous commit, the same traffic produces costs a thousand times smaller, and the quotas can no longer be reached: a test run that previously exceeded the silver quota of 15 USD now costs about a cent, and the monthly `tokenQuota` of 1,000,000 tokens is reached long before the cost quota is. That would leave the lab's central scenario, a subscription exceeding its cost quota and being suspended by the alert-driven Logic App, unable to fire at all. Scale the three quotas by the same factor the prices moved, restoring the previous behaviour exactly: whatever traffic tripped a quota before still trips it now, and the dashboard shows the same relationship between CostQuota and TotalCost. Also note in the variables cell that these values are sized for a short demo run, so they are not mistaken for realistic budgets and raised back to a magnitude that can no longer be reached.
Contributor
Author
|
@microsoft-github-policy-service agree company="Microsoft" |
There was a problem hiding this comment.
🟡 Changes recommended
Correct the pricing-unit note and remove its unconditional request-count claim.
Get a fresh assessment by requesting another Copilot review.
Pull request overview
This PR fixes a 1000× overstatement in Foundry token costs and rescales demo quotas accordingly.
Changes:
- Removes the erroneous
* 1000price transformation. - Rescales demo quotas to
0.015/0.010/0.005. - Updates pricing labels and documentation.
File summaries
| File | Summary |
|---|---|
labs/finops-framework/finops-framework.ipynb |
Corrects pricing ingestion, quotas, display units, and related documentation. |
Review details
- Files reviewed: 1/1 changed files
- Comments generated: 1
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Alex Vieira (vieiraae)
approved these changes
Sep 16, 2026
Alex Vieira (vieiraae)
merged commit Sep 16, 2026
1679e31
into
Azure-Samples:main
4 of 5 checks passed
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Fixes #397. Two commits: correct the prices, then rescale the quotas that were calibrated against the wrong ones.
The prices
The Retail Prices API returns Foundry token meters with
unitOfMeasureof1K, soretailPriceis already a per-1000-token price. The notebook multiplies it by 1000 before writing it toPRICING_CL, but every consuming query already divides by 1000:Each token ends up charged the price of a thousand tokens. For 1M input tokens on gpt-4.1-mini that's 400 USD reported instead of 0.40 USD.
The same KQL backs
alert-suspend-subandalert-activate-sub, so cost quotas trip about a thousand times too early and subscriptions get suspended almost as soon as they serve traffic.The quotas
Correcting the prices on their own would leave the lab's central scenario unable to fire, so the second commit deals with that.
costQuotais 15/10/5 USD. Those values only work because costs are inflated: reaching the silver quota of 5 USD takes roughly 1,000 tokens today. With correct prices it takes 1,000,000, and the monthlytokenQuotaof 1,000,000 is hit first, so no subscription can ever exceed its cost quota and the suspend/activate Logic App never runs.Scaling the quotas by the same factor the prices moved, to 0.015/0.010/0.005, restores the previous behaviour exactly: whatever traffic tripped a quota before still trips it, and the dashboard shows the same relationship between CostQuota and TotalCost.
The variables cell now says these are demo-sized, so they aren't mistaken for realistic budgets and raised back to a magnitude that can't be reached.
Breaking change
No. Rows already in
PRICING_CLkeep their values, but consumers read witharg_max(TimeGenerated, *) by Model, so the corrected row wins on the next ingestion. Anyone who already tunedcostQuotafor their own traffic will want to rescale it the same way.Type
Bugfix.
How to test
The premise needs no deployment:
One item,
retailPrice: 0.0004,unitOfMeasure: 1K. All six meters in the defaultmodels_configbehave the same.I also deployed the lab, ingested the corrected prices and ran the workbook's own KQL against the workspace. 1135 prompt + 1135 completion tokens on gpt-4.1 gives
0.01135; the same query on the old values gives11.35.result.pnghere showsTotalCost: 10.072for 2.27k tokens, which is that inflated magnitude.What to check
The KQL is deliberately untouched. The workbook, dashboard and both alert rules already assume a per-1K price, so correcting the ingested value is enough and nothing else has to move.
The display-only table earlier in the notebook keeps its
*1000; only its column header changed, to state the unit. That value is never ingested.The markdown note that stated the incorrect assumption is corrected.
Other
Introduced in c329179 (#140). One file, +9/-6.
result.pngstill shows the old magnitudes and would want regenerating at some point, though that needs a run in your environment rather than mine.