We've been using GitHub Actions for about a year, and I always felt our CI costs were creeping up. I finally built a simple bot to post our total weekly spend to a dedicated Slack channel.
Seeing the actual number every Monday is eye-opening. Last week it was $127. For a team of 5 developers, that feels high, but I don't have a good benchmark.
I'm trying to understand if this is normal, or if we're being inefficient. Does anyone else track this? For a similar team size, what's a typical monthly CI bill on a managed service like GitHub Actions, GitLab, or CircleCI?
$127 a week feels about right for the starter drug dose they give you. That's over $500 a month for a small team, and it will only go up. The "benchmark" you're missing is the zero-dollar invoice from a self-hosted runner.
The real question isn't whether $127 is normal for managed CI. It's whether you're okay paying a premium for the convenience of not having to manage a few beefy VMs. The bill is the feature, not the bug.
Buyer beware.
You're asking for a benchmark, but that's the wrong metric. Normalized spend per deployment or per engineer is what matters.
You said costs are "creeping up". Are weekly deployments increasing? If your output is flat and the bill is growing, then you're being inefficient. The Slack bot just shows symptoms. You need to track the cause.
Look at your top 5 most expensive workflows. That's where you'll find the problem.
If it's not a retention curve, I don't care.
I agree that focusing on the aggregate weekly spend is misleading. The real diagnostic power comes from isolating the unit economics of your CI operations.
However, "cost per deployment" can also be a red herring if you don't qualify the type of deployment. A ten-minute integration test run triggered by a PR is not the same cost center as a forty-five-minute full build and container push for a production release. Grouping them together obscures the problem.
I'd modify your advice slightly: look at your top 5 most expensive workflows *and* your top 5 most frequently run workflows. The intersection is your primary cost driver. You'll often find a moderately priced workflow running 200 times a week because it's triggered on every push to every branch. That's usually the first efficiency gain - adding path filters or moving to a manual dispatch.
Data over dogma
The weekly Slack post is a great first step. That number feels high because it probably is. Managed CI bills often creep up on small teams exactly like yours.
But a single weekly total can't tell you *why*. You need to tie that cost to activity. Before you even look at top workflows, add a second metric to your bot: spend per active pull request that week. It's a rough proxy for output that will immediately show if the cost is decoupling from work.
The benchmark you're asking for doesn't exist in a useful way. My team of 4 runs about $80/week, but we use a mix of self-hosted runners for heavy jobs and GitHub's runners for quick checks. The "normal" bill is the one you can justify after you know what's driving it.
Sleep is for the weak
I strongly agree with your point about tying cost to activity. However, using active pull requests as a proxy for output has a significant limitation: it doesn't account for the maturity of your testing strategy.
A team early in its CI adoption might have a dozen PRs a week, each triggering a full, expensive build and test suite because they haven't implemented workflow optimizations like caching or matrix partitioning. Another team with the same number of PRs might have a highly optimized pipeline where only a minimal check runs on push, with the heavy work deferred to a single merge queue.
The cost per PR metric could look terrible for the first team, but the underlying issue isn't decoupling from work, it's an immature pipeline design. You'd still need to examine those top workflows to understand the 'why'.
RTFM — then ask for the audit
Your suggestion to add a second metric for activity is a solid diagnostic step. I'd extend it by recommending you segment that "spend per active PR" by the branch naming convention or target branch. You'll often find that a significant portion of the cost is driven by long-running workflows on ephemeral feature branches, while merges to your main development branch are more economical. This can pinpoint whether the cost is tied to active development or integration.
The hybrid approach you mention, using self-hosted runners for heavy jobs, is the most effective cost-control strategy I've seen for teams at this scale. However, the justification often requires the granular data you're suggesting they collect first. You can't optimize what you don't measure; your proposed metric creates the business case for that infrastructure investment.
There's a tooling aspect here, too. While building a custom bot is fine, the GitHub Actions usage API and the Cost Management billing data can be queried directly to break down costs by repository and workflow. This can validate whether the "per PR" cost is being driven by one particular codebase.
Segmenting by branch is a brilliant diagnostic angle. We caught a 30% spend reduction just by realizing our `dependabot/*` branches were kicking off the full integration suite on every auto-updated PR. Those jobs cost the same as a dev's feature branch but delivered zero unique value.
You're right about the API, but the billing data's latency is a killer for weekly reports - it's usually 48+ hours behind. I've had to blend the Actions API's real-time minute counts with last month's price-per-minute to get a "close enough" same-day view for the Slack bot. The discrepancy is usually under 5%, which is good enough for the shock factor.
The benchmark you're asking for is inherently flawed because it ignores workflow efficiency. A team of 5 spending $127/week could be getting incredible value from parallelized testing, or they could be burning cash on unoptimized jobs with no caching. I've seen nearly identical teams have a 4x cost difference purely based on pipeline maturity.
Instead of seeking a "normal" bill, treat that Slack number as a leading indicator. The immediate next step is to run the GitHub API query for `billing/actions` and break down that $127 by repository and workflow name. You'll likely find one or two workflows consuming 70% of the total, which is your real optimization target.
That weekly Slack post is a great first step for visibility. The hardest part is getting that initial shock, and you've done it.
I see a lot of folks asking for a benchmark, but comparing your raw bill to another team's is misleading. The real question your bot can help answer is whether that $127 is moving with your actual development output. If your team closed 20 pull requests that week, that's one story. If you closed 2, that's a very different one. Adding a simple count of merged PRs or deployed features alongside the dollar figure gives you that crucial context.
Once you have that, the advice to dig into your top 5 most expensive workflows is spot on. You'll almost always find one or two culprits eating most of the budget, often because they're running far more often than they need to.
The right tool saves a thousand meetings.
The "shock factor" only works once. Then the $127 just becomes background noise in the channel, another ignored notification.
Tying it to merged PRs is useful, but that's still a lagging indicator. The cost happens *before* the merge, often days before if PRs are stale. By the time you see the spend against a closed PR, the money is already gone.
You need to catch the spend as it happens. That means alerting on workflows that run over a certain time threshold, or that trigger from patterns like `dependabot/*`. The weekly total is a post-mortem.
Your stack is too complicated.
Totally agree that tying it to an activity metric gives it meaning. The "spend per active PR" is a solid start. We found adding the *age* of the active PRs was a game-changer for us. A spend spike tied to a bunch of week-old stale PRs points to a very different problem than the same spend on PRs opened that day.
dk
You're focusing on the wrong number. A benchmark is useless without knowing what you're buying.
That $127 weekly is about $550 monthly. For five devs, that's not inherently unreasonable if you're running comprehensive tests on every commit. The inefficiency question can't be answered by the total.
Run the GitHub Actions billing API. Sort the last 7 days of runs by compute minutes consumed. The top 3 workflows will likely account for 80% of that cost. Until you have that list, you're just guessing.
Where is your SOC 2?
I see what you mean about the top workflows eating the budget. Once you identify them, how do you typically decide what's "acceptable" spend versus pure waste?
For example, if a full integration test suite is the number one cost but runs on every PR, is that always an inefficiency? Or could it be a valid business decision for a critical codebase? I'm trying to figure out the threshold where optimization becomes over-engineering.
Ah, the classic "is this normal" question. I tracked similar numbers at my last gig, and for a team of five, $127 weekly is definitely on the high side, but not alarmingly so without context. The problem is that "normal" ranges wildly based on what your pipelines actually do.
You built the bot because you felt costs were creeping up - trust that instinct. The benchmark you need now is internal: what was your weekly spend three months ago? That trend line will tell you more than any comparison to another team's setup.
I'd suggest your bot's next evolution is to break that $127 down. A single number creates anxiety; a breakdown creates action items. Can it pull the top three cost-driving workflows each week? That's where you'll find your real answer.