Track GitHub Copilot token usage by model, team, and repo

laptop screen displaying colorful code

Counting how many developers have a Copilot seat tells you almost nothing about what your organization is actually consuming. Different teams pick different models, agentic workflows multiply model calls per request, and large repository contexts balloon input tokens even when the generated output stays small.

A practical tracking system needs more resolution. Here is how to build one in C#, and what to watch out for once you have the data.

‍ Start With a Normalized Usage Record

Define a single internal model before collecting anything. Separating input and output tokens from the start makes the data more useful later:

public sealed record ModelUsage(
    string UserId,
    string Team,
    string Repository,
    string Model,
    long InputTokens,
    long OutputTokens,
    DateTimeOffset Timestamp)
{
    public long TotalTokens =>
        InputTokens + OutputTokens;
}

That split matters because input tokens often grow for reasons unrelated to how much code Copilot generates. A large repository context raises input usage while output stays flat. You want to see that distinction in your data.

Aggregate by Model, Team, and Repository

Once records are collected, LINQ makes it straightforward to slice them. A model-level summary:

var usageByModel = usageRecords
    .GroupBy(x => x.Model)
    .Select(group => new
    {
        Model = group.Key,
        Requests = group.Count(),
        InputTokens = group.Sum(x => x.InputTokens),
        OutputTokens = group.Sum(x => x.OutputTokens),
        TotalTokens = group.Sum(x => x.TotalTokens)
    })
    .OrderByDescending(x => x.TotalTokens)
    .ToList();

The same pattern applies for team and repository groupings. For teams, add a developer count and calculate tokens per developer. A 30-person team produces more raw usage than a 5-person team by default, so raw totals mislead. Normalize before comparing.

One firm warning from the article: treat tokens per developer as an analytical metric, not a productivity score. High usage does not automatically mean high output quality.

black and white penguin toy

⏱️ Add Time-Based Trend Tracking

Daily or weekly aggregates surface the patterns that matter most for capacity planning:

var dailyUsage = usageRecords
    .GroupBy(x => x.Timestamp.Date)
    .Select(group => new
    {
        Date = group.Key,
        Requests = group.Count(),
        TotalTokens = group.Sum(x => x.TotalTokens)
    })
    .OrderBy(x => x.Date)
    .ToList();

A sudden jump in token consumption has several possible causes: a new team starting to use Copilot, a shift to agentic workflows, larger repository context being passed, or repeated automated workflows. The data flags the spike. Your team has to investigate the reason.

Compare Models on Task Outcomes, Not Token Counts

A model that uses 600K tokens to complete 60 tasks is not more efficient than one that uses 1M tokens to complete 90 tasks. The source article makes this explicit with a TokensPerCompletedTask calculation:

public static double TokensPerCompletedTask(
    ModelPerformance performance)
{
    if (performance.CompletedTasks == 0)
    {
        return double.PositiveInfinity;
    }

    return (double)performance.TotalTokens
        / performance.CompletedTasks;
}

The catch: your definition of “completed task” must be consistent across models or the comparison is meaningless.

️ Keep Usage and Cost Separate

Token counts and actual billing are related but not the same thing. Depending on your Copilot plan, cost may not scale linearly with tokens. The article is direct on this: do not invent a fake per-token rate and multiply it out. Instead, store reported cost as a separate nullable field alongside your usage data:

public sealed record UsageSummary(
    string Model,
    long InputTokens,
    long OutputTokens,
    long TotalTokens,
    decimal? ReportedCost);

If your GitHub environment provides cost data, store it there. If it does not, leave it null rather than fabricating a number.

Privacy and Retention

Usage records can contain user identifiers, repository names, prompts, and generated code. The article recommends collecting only what you need. If the goal is model usage reporting, a minimal record of user, team, repository, model, token counts, and timestamp is considerably safer than storing full AI conversations.

Define a retention policy before you start collecting. Raw usage records warrant a shorter retention window. Aggregated metrics can be kept longer for trend analysis without holding onto every individual interaction.

Common Mistakes to Avoid

  • Treating token counts as a direct proxy for developer productivity
  • Comparing teams by raw usage without normalizing for team size
  • Assuming token count equals cost under any pricing model
  • Storing complete prompts and responses when aggregate counts would suffice
  • Using fixed anomaly thresholds without investigating context first
  • Ignoring model mix changes when total organizational usage shifts

The full article includes a troubleshooting checklist covering timestamp handling, duplicate event removal, and the difference between user requests and model calls in agentic workflows, worth reading if you are building this into a production pipeline.

Stay on top of AI & Automation with BizStack Newsletter
BizStack  —  Entrepreneur’s Business Stack
Logo