Try it free

Forecast costs with run-rate projections

  • Latest Dynatrace
  • Tutorial
  • 10-min read
  • Published May 26, 2026

Account Management already gives you a built-in forecast, but it only goes as far as environment and capability level. When you need to understand growth rates, project spend across 30/60/90-day windows, or calculate exactly when a budget alert will fire, DQL fills the gap.

This tutorial uses Full-Stack Monitoring as a worked example throughout. Once you understand the pattern, applying it to any other capability is a matter of changing the filter event.type and the rate card values.

All USD figures in this tutorial use the public list price of $1,000 per 100,000 GiB-hours (March 2026). Actual costs depend on your negotiated DPS contract. Use these queries for directional analysis and relative comparisons, not invoice reconciliation.

Who is this for?

This tutorial is for FinOps practitioners, engineers, and platform team leads who need to go beyond the Account Management overview, either to quantify a trend they can already see, or to set an evidence-based budget alert threshold.

What will you learn?

In this tutorial, you'll learn how to:

  • Read the built-in Account Management forecast and understand its limits.
  • Calculate a 30-day average daily burn rate for any capability.
  • Measure week-over-week growth and distinguish signal from noise.
  • Project spend at 30, 60, and 90 days using a compounding growth model.
  • Calculate how many days remain at the current burn rate before a budget alert fires.

Before you begin

Prerequisites

  • Access to Account Management with Subscription viewer permissions.
  • DQL query permissions on the dt.system.events table in at least one environment.

Prior knowledge

  • Basic familiarity with DQL billing events. If you're new to dt.system.events, start with Where to view your costs.
  • Budget alerts configured in Account Management for the capability you want to monitor. For more information, see Budget alerts.

Forecast DPS costs with run-rate projections

1. Check the built-in Account Management forecast

Before writing any DQL, check what Account Management already shows you.

  1. Go to Subscription > Overview and review the Budget Summary:

    ComponentWhat it tells you

    Annual commitment + days remaining

    Your contractual baseline.

    Forecast line chart

    Dynatrace's own ML projection through end of subscription period.

    Forecast events panel

    The date your forecasted usage will exceed your annual commitment, plus the projected on-demand overage.

    The built-in forecast becomes available once your account has 15 or more days of cost data. Until then, use the DQL steps below.

  2. Review your budgets (Subscription > Cost Management > Budgets) to check your configured alert thresholds. Three defaults are pre-configured at 75%, 90%, and 100% of your annual commitment.

If Account Management already answers your question, you're done and can skip the rest of this tutorial. If not, continue to the next steps to learn where DQL can help you:

NeedAccount ManagementDQL

Capability-level forecast

No

Yes

Cost center or team-level breakdown

No

Yes

30/60/90-day scenario table

No

Yes

Days until a specific threshold fires

No

Yes

2. Calculate your daily burn rate

Establish how much Full-Stack Monitoring costs per day on average and project that 30 days forward.

Run this query:

fetch dt.system.events, from: -30d
| filter event.kind == "BILLING_USAGE_EVENT"
| filter event.type == "Full-Stack Monitoring"
| dedup event.id
| fieldsAdd day = bin(timestamp, 1d)
| summarize daily_gib_hours = sum(billed_gibibyte_hours), by: {day}
| summarize avg_daily_gib_hours = avg(daily_gib_hours)
| fieldsAdd avg_daily_cost_usd = avg_daily_gib_hours / 100000.0 * 1000
| fieldsAdd projected_30d_cost_usd = avg_daily_cost_usd * 30
| fields avg_daily_gib_hours, avg_daily_cost_usd, projected_30d_cost_usd

The result is a single row:

avg_daily_gib_hoursavg_daily_cost_usdprojected_30d_cost_usd

48,200

$482.00

$14,460.00

projected_30d_cost_usd is your flat run-rate baseline, with no growth assumed. Use it as the floor for the scenario table in Step 4.

If your fleet changed recently (hosts onboarded, decommissioned, or switched monitoring mode), the 30-day average will be diluted. Change from: -30d to from: -7d to use only the post-change baseline.

| dedup event.id is mandatory in every billing query. Dynatrace refreshes metering records when correcting measurements. Without it, the same consumption period is counted multiple times and figures appear 10–30% higher than they are.

3. Measure week-over-week growth rate

Is consumption flat or growing? Compare the current week to the previous week to find out.

Run this query:

fetch dt.system.events, from: -14d
| filter event.kind == "BILLING_USAGE_EVENT"
| filter event.type == "Full-Stack Monitoring"
| dedup event.id
| fieldsAdd week = if(timestamp >= now() - 7d, "current", else: "previous")
| summarize
current_gib_hours = sum(if(week == "current", billed_gibibyte_hours, else: 0.0)),
previous_gib_hours = sum(if(week == "previous", billed_gibibyte_hours, else: 0.0))
| fieldsAdd growth_rate = (current_gib_hours - previous_gib_hours) / previous_gib_hours
| fieldsAdd growth_pct = round(growth_rate * 100, decimals: 1)
| fields previous_gib_hours, current_gib_hours, growth_pct

The result is a single row:

previous_gib_hourscurrent_gib_hoursgrowth_pct

320,100

377,700

+18.0%

Reading the result:

  • growth_pct below 5%: consumption is effectively flat; the Step 2 run-rate projection is a reliable estimate.
  • growth_pct between 5–15%: moderate growth; run Step 4 to understand the trajectory.
  • growth_pct above 15%: significant growth; continue to Steps 4 and 5 and consider setting a capability-scoped budget alert.

A single week of growth is not a trend. Two consecutive weeks in the same direction is the minimum signal worth acting on.

4. Build a 30/60/90-day scenario table

Compound the growth rate forward to understand the 90-day trajectory. This query takes the current week as the weekly baseline and projects at 30, 60, and 90-day intervals.

Run this query:

fetch dt.system.events, from: -14d
| filter event.kind == "BILLING_USAGE_EVENT"
| filter event.type == "Full-Stack Monitoring"
| dedup event.id
| fieldsAdd week = if(timestamp >= now() - 7d, "current", else: "previous")
| summarize
current_gib_hours = sum(if(week == "current", billed_gibibyte_hours, else: 0.0)),
previous_gib_hours = sum(if(week == "previous", billed_gibibyte_hours, else: 0.0))
| fieldsAdd growth_rate = (current_gib_hours - previous_gib_hours) / previous_gib_hours
| fieldsAdd current_weekly_cost_usd = current_gib_hours / 100000.0 * 1000
| fieldsAdd projected_30d_usd = current_weekly_cost_usd * pow(1.0 + growth_rate, toDouble(30) / 7.0)
| fieldsAdd projected_60d_usd = current_weekly_cost_usd * pow(1.0 + growth_rate, toDouble(60) / 7.0)
| fieldsAdd projected_90d_usd = current_weekly_cost_usd * pow(1.0 + growth_rate, toDouble(90) / 7.0)
| fields
growth_pct = round(growth_rate * 100, decimals: 1),
current_weekly_cost_usd,
projected_30d_usd,
projected_60d_usd,
projected_90d_usd

The result is a single row. The first column is the input; the remaining three are the projected costs.

Growth rate and current baseline:

growth_pctcurrent_weekly_cost_usd

+18.0%

$3,777

Projected spend:

projected_30d_usdprojected_60d_usdprojected_90d_usd

$19,100

$28,300

$41,900

Compare projected_90d_usd against your Full-Stack Monitoring budget alert threshold. If the projected value exceeds your threshold, that alert will fire before 90 days are up. Continue to Step 5 to calculate exactly when.

This is a scenario, not a forecast. The query assumes the current week's growth rate continues unchanged. Real-world consumption does not compound linearly. Host counts stabilize, deployments complete, auto-scaling settles. Use this to identify risk, not to predict an invoice.

5. Calculate days until your budget alert fires

Given a known budget threshold, calculate how many days remain at the current burn rate before Account Management sends the notification email.

Replace 5000.0 in the query with your Full-Stack Monitoring budget threshold. You can find your threshold in Budgets (Account Management > Subscription > Cost Management > Budgets).

fetch dt.system.events, from: -30d
| filter event.kind == "BILLING_USAGE_EVENT"
| filter event.type == "Full-Stack Monitoring"
| dedup event.id
| fieldsAdd day = bin(timestamp, 1d)
| summarize daily_gib_hours = sum(billed_gibibyte_hours), by: {day}
| summarize avg_daily_gib_hours = avg(daily_gib_hours)
| fieldsAdd avg_daily_cost_usd = avg_daily_gib_hours / 100000.0 * 1000
| fieldsAdd budget_threshold_usd = 5000.0
| fieldsAdd days_until_alert = round(budget_threshold_usd / avg_daily_cost_usd, decimals: 0)
| fields avg_daily_cost_usd, budget_threshold_usd, days_until_alert

The result is a single row:

avg_daily_cost_usdbudget_threshold_usddays_until_alert

$482.00

$5,000.00

10 days

Use days_until_alert to decide what action is needed:

Days remainingStatusAction

> 90

On track

No immediate action needed.

30–90

Watch

Review with team; check if growth is expected.

< 30

Escalate

Engage account team; evaluate cost reduction levers.

Budget alert thresholds in Account Management use your actual contracted costs, while this query uses list prices. The two numbers are directionally comparable but not identical. If no Full-Stack Monitoring budget exists yet, create one scoped to the relevant environment and capability. For more information, see Budget alerts.

Budget alerts in Account Management are evaluated daily after 12:00 UTC and fire once on the day a threshold is crossed. There is no intra-day alerting.

Common pitfalls

PitfallImpactFix

Missing dedup event.id

Usage figures appear 10–30% higher than reality.

Apply before every summarize.

Congratulations!

You can now forecast DPS spend beyond what Account Management shows out of the box. Specifically, you can:

  • Read the built-in forecast and know when to supplement it with DQL.
  • Calculate a 30-day burn rate baseline for any capability.
  • Measure week-over-week growth and decide whether it warrants action.
  • Project spend at 30, 60, and 90 days using a compounding growth model.
  • Calculate how many days remain before a specific budget alert fires.

Next steps

  • Set or update a capability-scoped budget alert based on your results in Step 5 (Calculate days until your budget alert fires). For more information, see Budget alerts.
  • If growth is unexpected, investigate the source. For more information, see Trace a cost spike to its root cause.
  • Apply the same query pattern to other capabilities by changing filter event.type and the rate card divisor.

Related topics

  • Use the built-in forecast
  • Forecast costs for new resources
  • Where to view your costs
  • Budget alerts
Related tags
Dynatrace Platform