Edit

Cost baseline for startups

This guide outlines a cost baseline you can set up over a weekend and keep running with minimal effort. It covers four connected elements: scoped budgets by environment, team, and product; alerts that surface real anomalies instead of noise; a tagging strategy that links spending to unit economics; and a simple worksheet for cost per customer or cost per action. Each section is labeled by startup stage so you can decide what to do now and what to postpone.

In this article you'll learn how to:

  • Define a small, durable tagging strategy that maps Azure resources to environment, team, product, and customer.

  • Create budgets at the subscription and resource-group scope, filtered by tag, with thresholds that match how your team actually responds.

  • Configure tiered alerts so the right person hears about the right kind of spike.

  • Build a cost-per-customer or cost-per-action worksheet from billing data and a single business metric.

  • Recognize which Cost Management features depend on your Azure billing type, and what to do if a feature isn't available to you yet.

Prerequisites

  • An Azure subscription with at least one resource group and a few resources running. A free trial or a pay-as-you-go subscription both work.

  • Owner or Contributor role on the subscription, plus Cost Management Contributor (or higher) so you can create budgets and alerts. If you don't have these roles, ask whoever owns the subscription to grant them.

  • Familiarity with the Azure portal. You don't need prior experience with Microsoft Cost Management or Azure Monitor, and you don't need a FinOps practice or a dedicated cost owner.

Note

Cost and usage data is typically available within 8 to 24 hours, and budgets are evaluated against that data every 24 hours. Treat anything you see in the portal as roughly a day behind reality, and plan reviews accordingly.

Why this matters for startups

Early-stage cost discipline isn't about cutting spend for its own sake. It's about three practical outcomes: preventing a bad deployment or runaway loop from consuming a meaningful share of runway, understanding the real cost to serve each customer before setting pricing, and planning beyond the next funding milestone without an unexpected bill.

The cost baseline in the following section is deliberately small. It's a set of guardrails, not a finance practice. It assumes you have no dedicated platform team, no on-call FinOps engineer, and no spare cycles to write custom dashboards. Every step is achievable by a founding engineer in a single working session.

Build a tagging strategy tied to unit economics

Tags are key-value pairs you attach to Azure resources. Cost Management groups, filters, and breaks down spend by tag, so every budget, alert, and unit-economics calculation in this guide depends on having a small, consistent set of tags applied to almost everything.

Resist the urge to design a tag taxonomy with 15 dimensions. Four tags cover most early-stage needs:

Tag Example values Used for
env prod, staging, dev Separating the customer-impacting bill from the build-and-experiment bill.
team platform, ml, web Routing alerts to the people who can act on them.
product core-api, recommender, internal-tools Per-product budgets and per-product unit economics.
costCenter free-tier, paid, internal Splitting variable customer cost from fixed engineering cost.

Apply tags at create time, not after

Tags applied through a Bicep or Terraform template stay applied. Tags applied by hand drift the moment a teammate creates a resource in the portal. Two mechanisms keep this tagging strategy from rotting:

  • Azure Policy with the built-in policies Require a tag on resources and Inherit a tag from the resource group. The first policy blocks resource creation without the tag. The second policy propagates the tag down so you only set it once at the resource group level.

  • Resource group naming that mirrors the tags. A resource group named rg-core-api-prod is self-documenting, and it limits the blast radius of a misapplied tag.

Important

Some resource types (classic resources, a handful of managed services) don't accept tags or don't propagate them to billing rows. Verify your most expensive resource types support tagging before you build a budget that depends on the tag.

Example Bicep snippet

param env string = 'prod'
param team string = 'platform'
param product string = 'core-api'
param costCenter string = 'paid'

var commonTags = {
  env: env
  team: team
  product: product
  costCenter: costCenter
}

resource plan 'Microsoft.Web/serverfarms@2023-12-01' = {
  name: 'plan-${product}-${env}'
  location: resourceGroup().location
  tags: commonTags
  sku: {
    name: 'P1v3'
    tier: 'PremiumV3'
  }
}

Tip

If you already have untagged resources, run a one-time report with the Cost Analysis view grouped by Tag, and review the Untagged bucket. Anything large lives there. Tag those resources first. Backfill everything else by redeploying through your template.

Set budgets per environment, team, and product

A budget in Cost Management is a monthly (or quarterly, or annual) spending target with one or more thresholds that fire alerts when crossed. Budgets don't stop spending. They notify you, and at higher tiers they can trigger automation.

Most early-stage teams fall into the trap of a single subscription-wide budget. It fires when total spend crosses a number, which tells you almost nothing about why. Scope budgets the same way you scope blame: by environment, by team, and by product.

Scope Filter Why
Subscription None (catch-all) Last-line-of-defense alert at, for example, 120 percent of your monthly forecast.
Resource group Per env: prod, staging, dev Catches a runaway dev or staging workload before it eats prod's headroom.
Subscription Tag: product One budget per shipped product. Trends become legible per product.
Subscription Tag: team Optional once you have more than one team. Routes alerts to the right channel.

Pick thresholds that match how you react

Default Azure budgets include a single 80 percent threshold. That threshold is almost always wrong for an early-stage team. Use three thresholds that mirror the severity of your response:

  1. 50 percent of monthly budget: informational. Goes to an email or a low-priority chat channel. Nobody pages.

  2. 80 percent: action required. Goes to the team chat channel with the owner @mentioned. Someone confirms whether the trend is expected.

  3. 100 percent: incident. Goes to an action group that can page on-call, run an Azure Automation runbook, or post to a high-priority channel.

Caution

A 100 percent threshold that triggers an automation to deallocate or scale down a resource can save money and break production. Test the runbook against a non-production budget first, and never wire it to a customer-facing service without a manual approval step.

Create a budget with notifications in source control

The portal is fine for one-off budgets. To keep budgets in source control and apply them consistently across subscriptions, use an Azure Resource Manager (ARM) or Bicep template against the Microsoft.Consumption/budgets resource. The az consumption budget create preview command doesn't expose notification thresholds as flags, so templates (or the REST API) are the deployable path.

// Bicep: USD 5,000 monthly budget on a resource group, 50/80/100 percent actual cost alerts
targetScope = 'resourceGroup'

resource budget 'Microsoft.Consumption/budgets@2023-05-01' = {
  name: 'rg-core-api-prod-monthly'
  properties: {
    category: 'Cost'
    amount: 5000
    timeGrain: 'Monthly'
    timePeriod: {
      startDate: '2026-06-01'
      endDate: '2028-06-01'
    }
    notifications: {
      Actual_GreaterThan_50_Percent: {
        enabled: true
        operator: 'GreaterThan'
        threshold: 50
        thresholdType: 'Actual'
        contactEmails: [ 'oncall@example.com' ]
      }
      Actual_GreaterThan_80_Percent: {
        enabled: true
        operator: 'GreaterThan'
        threshold: 80
        thresholdType: 'Actual'
        contactEmails: [ 'team@example.com' ]
      }
      Actual_GreaterThan_100_Percent: {
        enabled: true
        operator: 'GreaterThan'
        threshold: 100
        thresholdType: 'Actual'
        contactRoles: [ 'Owner' ]
        contactGroups: [ '/subscriptions/<subscription-id>/resourceGroups/<resource-group-name>/providers/microsoft.insights/actionGroups/oncall' ]
      }
    }
  }
}

Note

Deploy by using az deployment group create --resource-group rg-core-api-prod --template-file budget.bicep. Validate the exact schema against the current Microsoft.Consumption/budgets reference before you roll it out across many subscriptions.

Optimize GitHub Copilot token costs

GitHub Copilot supports AI-assisted development, and usage-based billing ties some costs directly to token consumption. This model gives startup teams flexibility, but it also requires a disciplined approach to managing usage.

Understand how Copilot usage is billed

Copilot usage is measured in tokens, which represent the amount of data processed by the AI. Each interaction includes:

  • Input tokens (your prompt and code context)

  • Output tokens (the generated response)

  • Cached tokens (reused context from previous interactions)

While code completions remain included in all plans, features such as chat, agents, and code review consume tokens and contribute to overall cost.

Reduce cost through efficient usage

Startups can optimize costs by focusing on how developers interact with GitHub Copilot:

  • Write concise prompts to avoid unnecessary input tokens

  • Limit context to only relevant files or code snippets

  • Request shorter outputs to control generation size

  • Select lower-cost models for routine tasks and advanced models for complex scenarios

These practices reduce both input and output token consumption and improve overall efficiency.

Implement cost guardrails early

To maintain predictable spending, establish guardrails:

  • Set budget limits at the organization, team, or user level.

  • Monitor usage regularly through Copilot billing dashboards.

  • Restrict high-cost features (such as agent workflows) to critical use cases.

  • Adopt model usage policies, defaulting to lower-cost options.

Pooled credit models can help balance usage across teams, ensuring efficient allocation of resources.

Build a cost-aware development culture

Cost optimization is behavioral, not just technical. Encouraging developers to use Copilot purposefully, limit redundant queries, and follow prompt best practices can significantly reduce spending.

Combine usage discipline with governance controls to scale GitHub Copilot usage effectively, maximize productivity, and keep costs predictable.

Design alerts that deliver signal, not noise

A budget alert tells you when spending passes a threshold, but that alone isn't enough. The alerts that protect runway also show when spending is rising abnormally compared with your usual pattern. Two layers cover both needs:

Layer 1: threshold alerts on budgets

  • Defined in the previous section. Reliable, deterministic, and easy to reason about. Use them for the 50, 80, and 100 percent tiers.

  • Wire to an action group so you can configure the destination later. Even if the only destination today is an email, the indirection saves you a migration when you adopt Microsoft Teams, PagerDuty, or another tool.

Layer 2: anomaly alerts

Cost Management can detect unusual spend changes for a subscription based on your historical pattern. For setup, see Identify anomalies and unexpected changes in cost. Anomaly alerts help you catch the failure modes that a budget can't see, like a 3x daily run rate that's still under the monthly cap because the month just started. Anomaly detection runs once a day, roughly 36 hours after the end of the previous day, so expect a one- to two-day lag.

Caution

Cost anomaly alerts aren't available for Azure Government subscriptions. If you run on Azure Government, rely on threshold-based budget alerts plus your own scheduled review of the cost export.

Rules for keeping signal high

  • One owner per alert. If no human name is on it, archive it.

  • If an alert fires three times in a row for an expected reason, change the budget, change the threshold, or mute the tier. Don't let the team learn to ignore it.

  • Send 50 percent informational alerts to a separate channel from 100 percent incident alerts. Mixing them trains your team to treat the channel as low-priority noise.

  • Annotate every adjustment. When you raise a budget from 5,000 to 7,500, write the reason in the budget description. Future you and future hires need the context.

Caution

An action group with the wrong webhook can flood a chat channel during an outage. Test action groups by sending a manual test event before relying on them, and rate-limit any custom webhook you write yourself.

Build a cost-per-customer or cost-per-action worksheet

Total spend in the portal is a vanity metric. What matters is whether the marginal cost of one more customer (or one more inference, one more document processed, one more megabyte stored) is going down as you scale. You don't need a data warehouse to answer that question. You need an exported billing dataset and one denominator from your own product.

Step 1: export billing data

  • In the Azure portal, open Cost Management and create an Exports definition that writes a daily CSV of actual costs to an Azure Storage account. Pick the dataset Actual costs (the FOCUS 1.0 dataset, where available, is the preferred future shape).

  • Choose a flat folder structure and a stable file name. Your worksheet wants a predictable path.

Step 2: Pick one business metric per product

  • Choose metrics like active customers in the month, billed customers, completed jobs, or API calls billed. Use one number per product per day or per month.

  • Get this metric from the same place you pull the metric you use for fundraising or your operating review. Consistency matters more than precision.

Step 3: Divide

A minimal worksheet has four columns:

Column Source Example
Month Calendar 2026-05
Total cost (USD), tag product=core-api Billing export, summed 8,420
Active customers, core-api Product analytics 1,140
Cost per active customer (USD) Column 2 divided by column 3 7.39

Track the fourth column over time. The trend tells you whether your architecture and pricing are converging or diverging. A flat or rising number while customer count grows is the signal you most need to see, and it's invisible from the total bill.

Tip

If you have more than one product, build one worksheet per product. Don't average across products that have different economics. A storage-heavy product and an inference-heavy product hide each other's truth when blended.

Where to put the worksheet

Put the worksheet anywhere your team already looks weekly. A Microsoft Excel workbook in OneDrive or SharePoint refreshes from the Storage CSV with Power Query. A Power BI dataset works equally well if you already have one. A small Python script that posts a single number to a chat channel works too. Don't build a dashboard yet. Build the number.

Know which features depend on your billing type

Not every Cost Management feature is available on every billing account. Microsoft Customer Agreement (MCA), Enterprise Agreement (EA), and Microsoft Online Services Agreement (MOSA, the original pay-as-you-go) each expose a different surface area. The current support matrix lives in Understand Cost Management data and in the Exports and Budgets reference pages.

A simplified view, accurate as a starting point but verify against current Learn documentation for your specific agreement before you commit to a feature:

Feature MCA EA MOSA (pay-as-you-go)
Cost analysis in the portal Yes Yes Yes
Budgets (subscription, resource group, tag) Yes Yes Yes
Anomaly alerts (subscription scope, commercial Azure only) Yes Yes Yes
Scheduled exports to storage Yes Yes Yes, verify for your offer
FOCUS 1.0 dataset in exports Yes Yes Yes, verify for your offer
Reservations and Savings Plans recommendations Yes Yes Limited
Cost allocation rules Yes Yes Not available
Billing account-level Power BI app Yes Yes Not available

Important

If a feature you need isn't available on your billing type, you have two options: model the missing feature in the worksheet from the cost-per-customer section (cost allocation rules become a spreadsheet formula), or upgrade the billing relationship when you next renew. Don't block the cost baseline on a feature that's only available on a different agreement.

When this model isn't enough

The baseline model you just saw works well through the first two stages of Microsoft's startup architecture guidance. Growth signals that you need a more advanced model, rather than failure signals:

  • Your weekly review takes longer than 15 minutes because you're hand-reconciling tag drift.

  • You have more than five products, or more than three teams, each with their own budget channel.

  • Finance or your board starts asking for committed-spend forecasts, not just historical actuals.

  • Cost per active customer matters for sales pricing, and the worksheet refreshes too slowly.

  • You're considering reservations or savings plans for the first time, and you need a confident usage baseline.

Resist the temptation to adopt enterprise FinOps tooling early. The cost of running and staffing a full FinOps practice is significant, and the discipline matters far more than the tool. Push the spreadsheet model as far as it goes, then upgrade one piece at a time, starting with a richer export (FOCUS 1.0 into a warehouse) before you add a new dashboard.

Reference checklist

Run through this list once a month. Each item is a yes-or-no question:

  • Does every resource group have the env, team, product, and costCenter tags applied?

  • Is the Untagged bucket in Cost Analysis less than 5 percent of total spend?

  • Does every product have a budget at the subscription scope, filtered by product tag?

  • Does every budget have 50, 80, and 100 percent thresholds wired to a named owner?

  • Are anomaly alerts enabled at the subscription scope?

  • Was the cost-per-active-customer (or cost-per-action) worksheet refreshed in the last seven days?

  • Is the trend in the worksheet flat or declining for each product?

  • Was every alert that fired more than once in the last month investigated, tuned, or muted with a reason recorded?