Skip to content

CI was burning ~2,340 min/month — now fixed, here's the breakdown #261

@CalebisGross

Description

@CalebisGross

Summary

The ci/release-only change (#260, merged today) reduced CI from running on every PR and push to only running on release-please PRs and tag pushes. This issue documents the before/after numbers.

Before (March 1–20 actuals from Actions Usage Metrics)

Workflow Runs Linux min Windows min Total billed min
ci.yml 364 1,354 985 2,339
release-please.yml 83 83 83
release.yml ~19 31 3 51*
dependabot-updates 7 7 7
Total ~2,493

*Release also runs macOS builds (10x multiplier) — the 17 min macOS shown in the screenshot accounts for most of release.yml's cost.

Where 2,339 CI minutes came from

Trigger Runs Est. min Notes
PR (pull_request) 213 ~1,363 Every PR to main
Push to main 151 ~966 Redundant — CI already passed on the PR
Total CI 364 ~2,339

The push-to-main trigger alone was responsible for ~966 min — 39% of all CI — re-validating code that was already validated on the PR.

Each CI run spins up 7 jobs (test + build on both ubuntu and windows, plus lint and two gate jobs), billing ~6.4 min on average. Windows jobs are billed at 2x, which is why 985 billed minutes come from Windows despite each Windows job only running ~2 min.

Top branches by CI runs

Branch Runs
main (push) 50
release-please--branches--main 18
All feature/fix branches combined ~296

After (projected with ci/release-only)

Workflow Est. runs/month Est. billed min
ci.yml (release-please PRs + tags only) ~24 ~154
release-please.yml ~83 ~83
release.yml ~19 ~51
Total ~288

Estimated savings: ~2,200 min/month (88%)

What changed

PR #260 modified ci.yml to:

  1. Remove push: branches: [main] trigger — no more redundant CI on merge
  2. Add a should-run gate job that checks if the PR is from a release-please--* branch
  3. All other jobs depend on should-run and skip if it outputs false
  4. Keep push: tags: ["v*"] so CI runs as a final check alongside release builds
  5. Keep workflow_dispatch as an escape hatch

Regular PRs now rely on local pre-commit hooks (go fmt, go vet, golangci-lint) for quality.

Remaining optimization opportunities

  • Drop Windows from CI matrix: Windows jobs account for ~40% of CI minutes due to the 2x multiplier. The release workflow already builds and tests on Windows. Removing Windows from CI and relying on release builds would save another ~40% of remaining CI minutes (~60 min/month). Low risk for a pure-Go project with no Windows-specific code paths in CI.
  • Release builds macOS 10x multiplier: Each macOS build minute costs 10 Linux minutes. The current macOS build is fast (~0.7 min raw = ~7 billed), but worth noting if release frequency increases.

Data source

  • Screenshot: Actions Usage Metrics page, March 1–20, 2026
  • Run counts: gh api repos/AppSprout-dev/mnemonic/actions/runs (deduplicated, 494 total runs)
  • Job timings: gh run view on representative runs

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions