A command-line tool that shows your GitHub Copilot usage statistics in USD, with full detail.
It combines two data sources that normally live far apart:
| Source | What it gives you | USD basis |
|---|---|---|
Local Copilot CLI session store (~/.copilot/session-store.db) |
Every request you made: model, input/output/cache/reasoning tokens, AIU, latency, session, repo, branch | Estimated from configurable per-model rates |
| GitHub billing & Copilot REST APIs | Org seat counts, premium-request line items, Copilot metrics | Real amounts billed by GitHub |
Important: local figures are estimates. GitHub Copilot is seat-licensed, so token-derived cost represents equivalent API spend (an opportunity cost), not an invoice. Numbers from the GitHub billing API are the real billed amounts.
Requires Node.js 22.13+ (or 23.4+), which is where the built-in node:sqlite module became
available without a flag. Zero runtime dependencies. Works on macOS, Linux and Windows.
Install from npm:
npm install -g copilot-statsOr run it once without installing:
npx copilot-statsgit clone https://github.com/khanaffan/copilot-stats.git && cd copilot-stats
npm install
npm run build
npm link # makes `copilot-stats` available globallyOr run it directly without linking:
node dist/cli.jscopilot-stats # full summary of all local usage
copilot-stats models --since 30d # model costs for the last 30 days
copilot-stats sessions --top 10 # your ten most expensive sessions
copilot-stats org --org my-org # org seat + premium-request spend| Command | Description |
|---|---|
local |
(default) Personal usage from the local session store, costed in USD |
org |
Org-level Copilot billing: seats and premium requests, real USD from GitHub |
all |
Local and org reports together, with a combined total |
models |
Per-model breakdown: tokens, requests, AIU, USD, share %, avg $/request |
sessions |
Per-session breakdown: repo, branch, tokens, USD, duration, last used |
repos |
Cost rolled up by repository or working directory |
daily |
Time series by day, with --weekly / --monthly bucketing |
pricing |
Show the effective pricing table; pricing init writes an override file |
help, version |
Self-explanatory |
-s, --since <date> Start of window: YYYY-MM-DD, 7d, 4w, 6m, 1y, today, yesterday
-u, --until <date> End of window (inclusive)
-m, --model <name> Filter by model; repeatable or comma-separated
-r, --repo <name> Filter by repository or working-directory substring
-o, --org <name> Org for billing commands; defaults to all your orgs
--currency <code> Display currency (default USD); any code with an fxRates entry
-f, --format <fmt> table | json | csv
--json / --csv Shorthands for --format
-n, --top <n> Limit ranked table rows (or "all")
--daily/--weekly/--monthly Bucketing for the daily report
--db <path> Override the session store path
--pricing <path> Override the pricing config path
--token <token> GitHub token (else GITHUB_TOKEN, GH_TOKEN, gh auth token)
--redact Hash repository and path names in the output
--no-color Disable ANSI color
-v, --verbose Show diagnostics, API calls and warnings
Sample data below is illustrative — repository, session and branch names are fabricated.
Copilot Usage Summary
$15,616.47 estimated cost
13,334 requests across 13 models, 151 sessions
Window: the beginning → now
Billed request units: 118,932 (premium-multiplier weighted)
Tokens: 1.3B in / 9.3M out / 1.2B cache-read / 49.7M cache-write / 3.6M reasoning (2.6B total)
AIU: 99.5K
Cache hit ratio: 48.7% · Cache savings: $11,283.02
Avg cost/request: $1.17
Total duration: 37h 9m
Estimated from configurable rates — not a GitHub invoice.
Model Requests Billed Reqs Input Output Cache R Cache W Reasoning AIU Cost Share % Avg $/req
----------------------- -------- ----------- ------ ------ ------- ------- --------- ----- ---------- ------- ---------
claude-opus-4.8 5,264 78,610 528.3M 4.5M 502.0M 21.9M 2.0M 52.9K $9,429.04 60.4% $1.79
claude-opus-5 2,414 36,210 249.0M 1.7M 237.9M 9.2M 427.3K 23.1K $4,391.99 28.1% $1.82
claude-sonnet-5 4,213 4,213 412.5M 2.0M 393.5M 15.8M 652.9K 14.6K $1,445.19 9.3% $0.34
...
----------------------- -------- ----------- ------ ------ ------- ------- --------- ----- ---------- ------- ---------
TOTAL 13,334 118,932 1.3B 9.3M 1.2B 49.7M 3.6M 99.5K $15,616.47 100.0% $1.17
The default report also includes tables by repository, by session, a daily trend with inline bar charts, and a breakdown by initiator (user vs. agent).
Session Branch Requests Tokens Cost Duration Last used
--------------------------------- ------ -------- ------ --------- -------- ----------
acme/checkout-service main 464 99.6M $826.53 1h 19m 2026-07-17
acme/billing-api main 426 95.2M $824.83 54m 12s 2026-08-12
invoice-pdf-spike - 178 69.4M $601.73 48m 37s 2026-07-08
--------------------------------- ------ -------- ------ --------- -------- ----------
TOTAL (top 3 of 151) 1,068 264.2M $2,253.09 3h 2m
Date Requests Tokens Cost Chart
---------- -------- ------ --------- --------------------
2026-07-06 2,116 457.5M $3,704.60 ████████████████████
2026-07-13 3,218 573.8M $3,154.55 █████████████████░░░
2026-07-20 2,973 527.0M $3,194.64 █████████████████░░░
2026-08-10 2,261 416.9M $3,158.41 █████████████████░░░
copilot-stats models --json | jq '.data.rows[0].cost.total'
copilot-stats repos --csv > repo-costs.csvJSON is wrapped in a stable envelope:
{ "tool": "copilot-stats", "version": "0.1.0", "kind": "models",
"generatedAt": "2026-08-13T14:55:20.910Z", "data": { "...": "..." } }Costs are computed from a bundled pricing file with sensible list-price defaults for every model the Copilot CLI uses. Inspect the effective rates at any time:
copilot-stats pricingCreate your own override, which is deep-merged over the defaults:
copilot-stats pricing init # writes ~/.copilot-stats/pricing.jsonHow a request is priced:
- If the model has token rates configured for both
inputandoutput, cost = Σ (tokens ÷ 1,000,000 × rate) for input, output, cache-read and cache-write. Cache-read falls back to the input rate when unset; reasoning tokens are only billed separately if a distinctreasoningrate is configured (they are normally already counted inside output tokens). A model is only considered "token-priced" once bothinputandoutputare set — a partial override (e.g. just{ "input": 3 }) would otherwise silently bill the rest of that model's usage (usually the bulk of the cost) at $0. Partially-configured models fall back to AIU pricing instead and are flagged in a distinct "partially priced" warning naming the missing keys. - Otherwise cost = AIU ×
usdPerAiu, and the row is marked~in the table with a footnote. A multi-model group (session/repo/day/total) that combines a token-priced and an AIU-priced model reportscost.basis: "mixed"(also shown with the~marker), rather than misleadingly collapsing to"tokens".
Each request also carries a request_multiplier from GitHub (>1 for premium requests). This
is surfaced separately as billed request units (billedUnits in JSON/CSV, "Billed Reqs" in
the table) — the sum of COALESCE(request_multiplier, 1) across the group. It is purely
informational: it is not folded into token cost, since token cost is already computed
directly from token counts and per-token rates.
Use --pricing <path> to point at a different file for a single run.
All pricing is defined and computed in USD, which is also the default display currency.
Pass --currency <code> to restate every monetary figure using the fxRates in the pricing
config:
copilot-stats --currency EUR # € formatted table
copilot-stats models --currency JPY --json
copilot-stats repos --currency GBP --csv > repos.csv- Bundled rates:
USD(always 1),EUR,GBP,CAD,AUD,INR,JPY. - Add or override any code — including your own rate for an existing one — with an
fxRatesentry in~/.copilot-stats/pricing.json. Codes are case-insensitive. copilot-stats pricinglists the currencies currently available, and an unknown code fails with an error naming them.- Conversion is applied consistently to table, JSON and CSV output. JSON reports include a
currency: { code, rate }field and CSV rows acost_currencycolumn, so exported numbers are never ambiguous. - Rates are static config, not live FX — keep them current yourself if that matters.
Org commands need a token with elevated permissions. A standard gh auth login token does
not have them, and GitHub returns 404 (not 403) when they are missing:
gh auth refresh -h github.com -s admin:org -s manage_billing:copilotWithout those scopes, copilot-stats org still runs and prints an explanatory warning
per endpoint rather than failing, and copilot-stats all still shows your full local
report. Endpoints used:
GET /orgs/{org}/copilot/billing— plan type and seat breakdownGET /orgs/{org}/copilot/billing/seats— per-seat detailGET /organizations/{org}/settings/billing/usage— premium-request USD line itemsGET /orgs/{org}/copilot/metrics— active users, acceptance rates
Nothing is ever sent anywhere except to GitHub's own API. The local session database is
opened read-only (with WAL-safe fallbacks) and is never written to, so it is safe to
run while a Copilot CLI session is active. Session summaries, repository names and working
directory paths can be sensitive — use --redact to replace them with stable hashes when
sharing output.
npm run build # compile to dist/
npm test # compile and run the node:test suite (62 tests)
npm run dev # tsc --watchMIT
{ "usdPerAiu": 0.05, // fallback rate for models with no token rates "seatPricePerMonth": 39, // used to estimate org seat cost "fxRates": { "EUR": 0.92 }, // display currencies for --currency "models": { "claude-opus-5": { "input": 15, // USD per 1,000,000 tokens "output": 75, "cacheRead": 1.5, "cacheWrite": 18.75 } } }