← FinOpsAid blog

What is GitHub storage even charging us for? Reading the Storage page — FinOpsAid blog

What is GitHub storage even charging us for? Reading the Storage page

Net cost, month-over-month change, category splits and the SKU table — every figure on the FinOpsAid Storage page, and why this is the most trustworthy page in the product.

Storage is the page with the least explaining to do, because almost everything on it is billed. No modeling, no allocation rule, no attribution caveat — GitHub reports storage cost by category and SKU, and the page shows you that. If you want a number to take to finance without a footnote, it's here.

What the page can't do is tell you why the number is what it is. Storage has no owner in most organisations, and its cost is the accumulated residue of decisions nobody remembers making.

The KPI row

Tile What it counts Direction
Net Storage Cost Total net storage spend in scope, after discount. Billed. Worse.
This Month Current-month net, with a month-over-month delta chip. Worse.
Previous Month Last full month's net — the comparison baseline for the tile beside it.
Categories How many distinct storage categories carry spend. Neutral, but see below.

The Categories count is more useful than it looks. Storage on GitHub isn't one thing — it's Packages, Actions artefacts, Actions cache, LFS, Codespaces disks and more, each with its own retention behaviour and its own owner. A high category count means the cost is diffuse, and diffuse cost needs a different approach from concentrated cost.

This Month against Previous Month is a genuine like-for-like comparison, which is rarer than it sounds. Storage bills for existence rather than activity, so month-over-month movement is a real signal: it means something was created and not cleaned up, or something was finally deleted.

Cost by category

A donut with the net total in the centre, alongside a legend listing every category with its amount. This is where you learn what your storage bill actually is.

Storage categories have different owners and different fixes Actions artefacts and Actions cache are created by workflow configuration and fixed by changing retention settings in those workflows. Packages are published by release processes and fixed by pruning old versions. Large File Storage is added by developers committing binaries and fixed by history rewriting or policy. Codespaces disks are created by developers and fixed by retention policy. Each category needs a different owner to act. SAME BILL, FOUR DIFFERENT PEOPLE HAVE TO FIX IT CATEGORYCREATED BYFIXED BY Actions artefactsworkflow uploadsretention-days in the workflow Actions cachecaching stepscache key strategy · eviction Packagesrelease pipelinespruning old versions Git LFScommitted binariespolicy · history rewrite This is why “reduce storage spend” fails as a single action item. The donut tells you which conversation to have, and with whom. Start with the largest slice.
Read the donut as an ownership map, not just a cost split. Every category is created by a different process and fixed by a different team, and none of them will notice on their own — storage bills silently forever.

Storage spend over time

A daily area chart of net storage cost over the last 30 days.

Storage series behave differently from compute series and should be read differently. Compute is spiky because it tracks activity. Storage is a staircase: flat stretches punctuated by step changes when something large is created or deleted. A smooth upward drift means accumulation with no cleanup. A sudden step down means someone actually deleted something — worth finding out who and what, because that's your repeatable saving.

By SKU

The detail table: Product, SKU, Category (as a chip), Net — top 20 by net cost, sorted descending.

SKU is finer-grained than category, and it's where the answer usually is. "Packages" as a category tells you the family; the SKU tells you which package registry and which storage tier. When you need to hand a finding to a specific team, the SKU row is the evidence.

What this page doesn't tell you

There's no per-repository split. GitHub reports storage at the org level by category and SKU, not by repository — the same limitation as Copilot, for the same reason. The one exception is Actions cache storage, which does have a per-repository breakdown, and which lives on the GitHub Actions page because a workflow configuration is what created it.

There's no age dimension. You can see what storage costs, not how old it is. A 90-day-old artefact and a 900-day-old one bill identically and look identical here.

There's no "is this needed" signal. That judgement lives with whoever created the thing, which is exactly why storage accumulates.

What people get wrong on this page

The 60-second read

Frequently asked questions

Is GitHub storage cost billed or estimated?

Billed. GitHub reports storage cost directly by category and SKU, with no modeling, allocation rule or attribution caveat involved. That makes the Storage page one of the safest sources in FinOpsAid to quote to finance without a footnote.

Can I see storage cost per repository?

Not in general. GitHub reports storage at organization level by category and SKU, not by repository. The single exception is Actions cache storage, which does have a per-repository breakdown and appears on the GitHub Actions page because a workflow configuration created it.

Why does our storage bill keep growing?

Storage bills for existence rather than activity, so it only falls when someone deletes something — and nothing in GitHub prompts anyone to. A smooth upward drift on the daily chart means accumulation with no cleanup process; a step down means somebody actually removed data.

Want to see what your storage is actually made of? Connect your GitHub org — read-only and free during beta — or explore the demo first. There's a longer piece on the causes in why is GitHub storage on the bill. Next: how to read the Copilot page.