{"slug": "github-actions-cost-with-ai-coding-agents-the-duplicate-runs-behind-the-bill-and", "title": "GitHub Actions cost with AI coding agents: the duplicate runs behind the bill, and cheaper runners", "summary": "A developer running two private web apps reported on Reddit on 23 October 2026 that their GitHub Actions bill rose from about $738 in September to a projected $2,300–$2,450 in October, almost all of it Linux runner time, as coding agents pushed commits more often than people. At GitHub's $0.006 per Linux minute, that is roughly 123,000 minutes in September versus 383,000–408,000 projected for October, a 3.1x to 3.3x jump, and the post attributes the waste to duplicate runs on the same commit — one Camunda pull request put the waste at about 80 runner-minutes per merge. The post recommends counting workflow runs per commit and adding a concurrency block with cancel-in-progress before switching to cheaper runners such as Blacksmith, Namespace and Ubicloud, which list a minute at 33% to 79% less than GitHub.", "body_md": "# GitHub Actions cost with AI coding agents: the duplicate runs behind the bill, and cheaper runners\n\nWhen a [GitHub Actions](https://stackness.dev/tools/github-actions) bill jumps after coding agents start opening pull requests, the most likely cause is the same commit being tested more than once: every agent push runs the full suite, superseded runs keep going, and `push`, `pull_request` and `merge_group` triggers fire on one SHA. Count workflow runs per commit before changing anything else: one per workflow is healthy, and public issues from October 2026 show two or three, and one Camunda pull request put the waste at about 80 runner-minutes per merge. Switching runners comes second; [Blacksmith](https://stackness.dev/tools/blacksmith), [Namespace](https://stackness.dev/tools/namespace) and [Ubicloud](https://stackness.dev/tools/ubicloud) list a minute at 33% to 79% less than GitHub.\n\n## Why did my GitHub Actions bill triple after coding agents?\n\nA GitHub Actions bill triples with agents because agents push more often than people, and CI runs on every push. On 23 October 2026, a developer running two private web apps [posted on Reddit](https://www.reddit.com/r/ChatGPTCoding/comments/1xd9yqp/github_actions_getting_really_expensive_any/) that \"my September Actions bill was about $738, and my October usage was heading towards roughly $2,300–$2,450. Almost all of that is Linux runner time\".\n\nAt GitHub's $0.006 per Linux minute, that is about 123,000 minutes in September and 383,000 to 408,000 projected for October, a 3.1x to 3.3x jump (my arithmetic, before included minutes). The poster runs unit, database and browser tests through a [Mergify](https://stackness.dev/tools/mergify) merge queue, and works with coding agents, \"so there can be quite a lot of changes and test runs\". One commenter: \"My bill roughly tripled when I started letting an agent run CI on every commit it pushed.\" The [previous Stackness post on CI](https://stackness.dev/blog/ci-bottleneck-ai-generated-pull-requests-september-2026-numbers) covered queue time; this one covers the invoice, most common cause first.\n\n## Agent pushes run the full suite and superseded runs keep going\n\nAn agent that pushes three commits in a minute starts three full runs, and without a `concurrency` block all three finish, though only the last commit will ever merge. In one repository, [\"Agents push to branches about every 25 minutes\"](https://github.com/Midtown-Technology-Group/bifrost/pull/1385), and another found [\"Every force-push during review costs a full wasted run.\"](https://github.com/askturret/mcp/issues/687)\n\nTo check, list a pull request's runs: successful runs on commits that were later replaced should show as `cancelled`. The fix, from [GitHub's docs](https://docs.github.com/en/actions/how-tos/write-workflows/choose-when-workflows-run/control-workflow-concurrency), cancels in-progress runs for pull requests only, and keys the group on the workflow name so two workflows do not cancel each other:\n\n```\nconcurrency:\n  group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}\n  cancel-in-progress: true\n```\n\n## The same commit runs twice from push plus pull_request\n\nA workflow with both `on: push` and `on: pull_request` runs every commit on a pull request branch twice, once per event. One issue from 23 October describes it: [\"Every update to a branch with an open pull request therefore launches two identical full matrices for the same commit.\"](https://github.com/cindersocket/dfc-core/issues/103) Another repository counted about 157 runner-minutes for one change across its pull request and post-merge runs, and [\"about half of it re-tests a tree that has already passed\"](https://github.com/dudleylane/OrderProcessor/issues/314).\n\nTo check, group recent runs by commit and workflow. This reads the last 100 runs from the [runs API](https://docs.github.com/en/rest/actions/workflow-runs) and prints every commit that ran one workflow more than once (add an `Authorization: Bearer` header for a private repository):\n\n```\ncurl -s \"https://api.github.com/repos/OWNER/REPO/actions/runs?per_page=100\" | jq -r '.workflow_runs\n  | map(select(.event == \"push\" or .event == \"pull_request\" or .event == \"merge_group\"))\n  | group_by(.head_sha + .path) | map(select(length > 1))[]\n  | \"\\(.[0].head_sha[0:7])  \\(.[0].path)  \\(map(.event) | join(\" + \"))\"'\n```\n\nRun against `redhat-et/ProtoBot` on the morning of 25 October 2026, it printed the lines below; the last 100 runs change within hours, so yours will differ:\n\n```\n4da0533  .github/workflows/ci-workflow.yaml  push + push + merge_group\na3d744f  .github/workflows/ci-workflow.yaml  pull_request + push\n```\n\nThe fix is to limit `push` to the default branch and let `pull_request` cover branches. Drop the post-merge `push` run too only if what merges is the tree that was tested.\n\n## Merge queues test the same change again, and rebuild after failures\n\nA merge queue reruns CI on every entry by design, and adds two kinds of waste on top: duplicate triggers on the queue branch, and rebuilds after a failure.\n\nFirst, GitHub's queue builds on branches named `gh-readonly-queue/...`, so an unfiltered `push` trigger runs alongside `merge_group` on the same commit; [one such issue](https://github.com/redhat-et/ProtoBot/issues/312) estimates about 10 runner-minutes wasted per queue attempt. The run after merging can repeat it again: at [Camunda](https://github.com/camunda/connectors/pull/9597), the `merge_group` run and the post-merge `push` run tested the same SHA, \"about 80 runner-minutes wasted per merge\", until it dropped one of the two triggers on 19 October. Second, a failure throws away work: when an entry fails, [GitHub's queue](https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/configuring-pull-request-merges/managing-a-merge-queue) rebuilds the entries behind it, and [Mergify cancels later batches](https://docs.mergify.com/merge-queue/batches/) and puts their pull requests back in the queue.\n\nTo check, count `merge_group` runs per merged pull request; a ratio well above one means rebuilds. Look for runs with `event: push` on `gh-readonly-queue/` branches. The fix for the duplicate is one line:\n\n```\non:\n  push:\n    branches-ignore: [\"gh-readonly-queue/**\"]\n  merge_group:\n```\n\nThe fix for rebuilds is fewer failures in the queue, which leads to the next cause.\n\n## Flaky tests, re-runs, rounding and missing timeouts all bill again\n\nEvery re-run is billed again; re-running only the failed jobs bills only those jobs. [GitHub's own example](https://docs.github.com/en/billing/concepts/product-billing/github-actions): a 10-minute workflow that fails at minute 5 and is re-run costs 15 minutes. Each job is also rounded up to a whole minute, so ten 10-second gate jobs bill 10 minutes, and a job with no `timeout-minutes` can run for the default 360 minutes before GitHub cancels it.\n\nTo check, look for `run_attempt` above 1 in the runs API, and for job durations near 360 minutes or under 60 seconds. Read a failure before pressing re-run; fix or quarantine the flaky test; set `timeout-minutes` on every job; merge tiny jobs into one.\n\n## Copilot and claude-code-action spend minutes on the agent's own work\n\nSome agents run on Actions themselves, so they bill minutes before any CI starts. [GitHub Copilot](https://stackness.dev/tools/github-copilot)'s [cloud agent](https://docs.github.com/en/billing/concepts/product-billing/github-copilot-premium-requests) sessions use \"both GitHub Actions minutes and premium requests\", [Copilot code review](https://github.blog/changelog/2026-04-27-github-copilot-code-review-will-start-consuming-github-actions-minutes-on-june-1-2026/) has used Actions minutes on private repositories since 1 June 2026, and the [GitHub Action](https://code.claude.com/docs/en/github-actions) for [Claude Code](https://stackness.dev/tools/claude-code) \"runs on GitHub-hosted runners, which consume your GitHub Actions minutes\". [Codex](https://stackness.dev/tools/codex-cli) cloud and [Cursor](https://stackness.dev/tools/cursor)'s cloud agents run on their own machines; only the CI their pull requests trigger is yours.\n\nTo check, group the detailed usage report by `workflow_path`, the only report that has it. Group by `sku` first to confirm the money is Linux minutes, not storage or larger runners:\n\n*The Actions usage chart grouped by SKU, with GitHub's example data. Screenshot from [GitHub Docs](https://docs.github.com/en/billing/how-tos/products/view-productlicense-use) by GitHub, [CC BY 4.0](https://github.com/github/docs/blob/main/LICENSE).*\n\nThe fix is to cap turns and timeouts for Claude Code runs, and to keep GitHub Copilot's default, where its pushes run no workflows until someone clicks \"Approve and run workflows\".\n\n## What does a GitHub Actions minute cost against Blacksmith, Depot and Namespace?\n\nA 2-vCPU Linux minute on GitHub Actions costs $0.006 since GitHub's price cut of [1 January 2026](https://github.blog/changelog/2026-01-01-reduced-pricing-for-github-hosted-runners-usage/), down from $0.008. Third-party runners run the same workflows after a change to the `runs-on:` label, and most charge less per minute; [Depot](https://stackness.dev/tools/depot) now charges the same. List prices for a 2-vCPU Linux runner, read on 25 October 2026:\n\n| Runner | Linux x64, per minute | arm64 | What to know | \n|---|---|---|---|\n| GitHub-hosted, 2 vCPU, 8 GB | $0.006 | $0.005 | each job rounded up to a minute; 3,000 minutes included on Pro and Team | \n| [Blacksmith](https://www.blacksmith.sh/pricing) | $0.004 | $0.0025 | 3,000 free minutes a month | \n| [Depot](https://depot.dev/pricing) | $0.006 | $0.006 | was $0.004 until late August 2026, [per the Wayback Machine](https://web.archive.org/web/20260808/https://depot.dev/pricing) ; bills per second | \n| [Namespace](https://namespace.so/pricing) | $0.003, or $0.002 prepaid | same | that price is for 4 GB of RAM; 8 GB costs $0.006, or $0.004 prepaid | \n| [Ubicloud](https://www.ubicloud.com/docs/about/pricing) | $0.00125 standard, $0.002 premium | $0.00125 | premium is on by default; machines in Germany by default | \n| [RunsOn](https://runs-on.com/pricing/) | about $0.0009 to AWS on spot | not quoted | your own AWS account, plus a licence from €300 a year | \n\nPriced at these rates, the Reddit poster's projected October minutes would cost about $1,530 to $1,630 on Blacksmith, $770 to $820 on Ubicloud premium and the same as GitHub on Depot, before any speed-up (my arithmetic, list prices, no free tier). The poster is moving jobs to Ubicloud and reported a pilot \"51% lower\", without showing the numbers. A cheaper minute does nothing about minutes that should not run.\n\nOn Stackness, GitHub Actions is on 6 public stacks as of 25 October 2026, bots removed ([how I count](https://stackness.dev/about/data-sources)), and none lists Blacksmith or Depot yet; the [DevOps and infrastructure tools developers use](https://stackness.dev/categories/devops-infrastructure) show the rest of the CI picture.\n\n## Are self-hosted runners worth it for an agent-heavy repo?\n\nSelf-hosted runners cost nothing per minute on GitHub as of 25 October 2026: the $0.002 platform charge announced for March 2026 was [postponed, not cancelled](https://resources.github.com/actions/2026-pricing-changes-for-github-actions/). You pay in upkeep instead. GitHub stops queuing jobs on a runner that misses an update for 30 days, recommends ephemeral autoscaled runners, and [warns](https://docs.github.com/en/actions/reference/security/secure-use) that anyone who can open a pull request can compromise a self-hosted runner.\n\nAgent-written code is untrusted in the same way, so a reused machine on a desk is the riskiest setup. [RunsOn](https://stackness.dev/tools/runs-on) is the middle ground: fresh machines in your own AWS account, with the lifecycle managed. And on a single self-hosted runner, duplicate runs stop costing dollars and start costing queue time, 47 minutes in one of the issues above.\n\n## Move the browser suite to the merge queue, keep lint and unit tests on every push\n\nThe checks that can leave every push are the slow ones the merge queue repeats anyway: browser tests, end-to-end suites with a database, long integration matrices. Lint, type checks and unit tests stay on every push; the full suite runs once, on `merge_group`. The Reddit poster split CI this way. The commenter whose bill tripled split the pipeline and added concurrency groups, and reported \"Cut minutes by about 60% without losing the safety net\", an unmeasured figure from one repo.\n\nTwo GitHub rules decide whether the split keeps the safety net. A workflow skipped by a `paths` filter leaves its required check \"Pending\" and blocks the merge; a job skipped by `if` reports \"Success\", [even when it is a required check](https://docs.github.com/en/actions/how-tos/write-workflows/choose-when-workflows-run/control-jobs-with-conditions). Mergify can batch several pull requests into one run, at a price it [names itself](https://docs.mergify.com/merge-queue/parallel-checks/): \"hidden failures inside a passing batch can land on main\".\n\n## GitHub Actions bill: symptom, check, fix\n\n| If you see | Check | Fix | \n|---|---|---|\n| Two runs per commit with `push` and`pull_request` | runs API grouped by `head_sha` and`path` | `push` on the default branch only | \n| `push` runs on`gh-readonly-queue/` branches | runs API `head_branch` | `branches-ignore: [\"gh-readonly-queue/**\"]` | \n| Successful runs on superseded commits | runs per pull request, not `cancelled` | `concurrency` with`cancel-in-progress: true` | \n| Many `merge_group` runs per merged pull request | count against merged pull requests | fix flaky tests, avoid queue jumps, batch | \n| `run_attempt` above 1, jobs near 360 minutes | runs and jobs API | read failures before re-running; `timeout-minutes` | \n| One `workflow_path` dominates cost | detailed usage report | run that suite on `merge_group` only | \n| Copilot or Claude workflows in `workflow_path` | detailed usage report | turn and time caps; keep Copilot's approval gate | \n| Linux minutes still dominate after all of the above | usage report by `sku` | third-party runners, or ephemeral runners in your own cloud | \n\n## New posts by email\n\nAbout one email a week with what we published. No account needed.\n\n## Which of these do you use?\n\nNobody on Stackness runs Blacksmith yet. Tick what you use and be the first.\n\n[Play Lonny Eagle Amateur Skater 4A pixel art skateboarding game. Signing up opens it straight away.Sign up to play](https://stackness.dev/games/lonny-eagle)", "url": "https://wpnews.pro/news/github-actions-cost-with-ai-coding-agents-the-duplicate-runs-behind-the-bill-and", "canonical_source": "https://stackness.dev/blog/github-actions-cost-ai-coding-agents-duplicate-runs-and-alternatives", "published_at": "2026-10-25 10:06:09+00:00", "updated_at": "2026-10-25 10:42:29.227340+00:00", "lang": "en", "topics": ["ai-agents", "developer-tools", "ai-tools"], "entities": ["GitHub Actions", "GitHub", "Reddit", "Mergify", "Blacksmith", "Namespace", "Ubicloud", "Camunda"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/github-actions-cost-with-ai-coding-agents-the-duplicate-runs-behind-the-bill-and", "markdown": "https://wpnews.pro/news/github-actions-cost-with-ai-coding-agents-the-duplicate-runs-behind-the-bill-and.md", "text": "https://wpnews.pro/news/github-actions-cost-with-ai-coding-agents-the-duplicate-runs-behind-the-bill-and.txt", "jsonld": "https://wpnews.pro/news/github-actions-cost-with-ai-coding-agents-the-duplicate-runs-behind-the-bill-and.jsonld"}}