Technical

How to set a carbon budget for your CI pipeline and block merges when it breaks

A

Anand Srinivasan

20 Jul 2026 · 7 min read

Dashboards do not change behaviour. Merge blocks do.

This is the core insight behind carbon budgets in EmitCI. Engineers monitor dozens of dashboards. They respond to exactly one thing that prevents them from merging a pull request. If you want engineering teams to treat carbon as a real constraint — not a reporting metric that lands in someone's quarterly PDF — put it in the merge gate.

How it works

A carbon budget is a monthly CO₂ ceiling per repository. EmitCI tracks cumulative CI/CD emissions against the ceiling in real time. Two thresholds trigger actions.

At 80%, EmitCI sends an alert email to admins and optionally to a Slack channel. This is the early warning. The team still has room to land in-flight work, but they know the ceiling is close.

At 100%, EmitCI posts a failure commit status on every open pull request in that repository. The status check is called "EmitCI / carbon-report". The status message shows the current period emissions, the budget, and the percentage overage.

CI CHECK            STATUS    MESSAGE
──────────────────────────────────────────────────────────
✓ tests / ubuntu    passing   All 142 tests passed
✓ lint / eslint     passing   No issues found
✗ EmitCI / carbon   failing   12,400 gCO₂ used · Budget: 10,000 g · 124% over

→ Merge button is greyed out
→ Blocked until: (a) budget resets next month, or (b) admin raises the ceiling

The status check alone does not block merges. You have to add "EmitCI / carbon-report" to your repository's branch protection required status checks. That is a one-time GitHub configuration change — no YAML edits to your workflow files. Once it is added, the merge button is controlled by the carbon budget just like it is controlled by failing tests.

How to size the initial budget

Starting too tight creates noise. Starting too loose creates no behaviour change. The right initial budget is your current baseline with a small buffer.

SIZING METHOD 1 — Baseline + buffer (recommended for starting out)
  Step 1: Note your last 30-day CI emissions from the EmitCI dashboard
  Step 2: Set budget = last 30 days × 1.1  (10% headroom)
  Step 3: Review after 60 days. If you never approached the limit, tighten it.

SIZING METHOD 2 — Industry benchmark
  Step 1: Check your language percentile in EmitCI Benchmarks
  Step 2: Set budget = p50 value for your language and team size
  Step 3: This puts you at the industry median as a starting constraint

SIZING METHOD 3 — Reduction target
  If you have a public carbon reduction commitment (e.g. 20% reduction by 2026):
  budget = last year's total / 12 × (1 - target_reduction_rate)

For most teams, Method 1 is the right entry point. The goal in the first 90 days is not to enforce aggressive reduction — it is to make carbon visible in the development workflow. Once engineers can see the budget counter filling up, they start asking which workflows are using the most.

What happens when the budget breaks

The first time a repository hits its budget ceiling, the instinct is to raise the ceiling. Resist this for a week. Instead, look at what pushed you over.

BUDGET BUST — INVESTIGATION CHECKLIST
──────────────────────────────────────────────────────────────
1. Which workflows consumed the most this month?
   → Dashboard → Repository → By workflow

2. Did a single run spike far above the repo mean?
   → Anomaly detection will have flagged this

3. Is a specific branch or PR driving high run frequency?
   → Branch sprawl rule — >35% of runs on non-main branches

4. Did a new workflow get added without path filters?
   → Monorepo path filter gap or unconditional deploy rule

5. Is caching broken? (cache miss rate suddenly high)
   → Cache npm rule — hashFiles on wrong file

The answer is almost always one of these five.

After the root cause is fixed, raise the budget only enough to accommodate the corrected baseline. Do not raise it to absorb the broken pattern you just fixed.

The ratchet strategy

The most effective teams treat the budget as a ratchet — it only moves down. Set it at 110% of baseline, fix what pushes you toward the ceiling, then lower it to 100% of the new (improved) baseline, then 90%, and so on. This approach compounds improvements. Fixing cache keys, adding path filters, and right-sizing runners are one-time engineering tasks that permanently reduce the emissions floor.

Month 1    Budget: 11,000 gCO₂   Actual: 9,800 gCO₂   (baseline + 10%)
           Action: discovered uncached npm installs, fixed
Month 2    Budget: 9,000 gCO₂    Actual: 7,200 gCO₂   (new baseline + 10%)
           Action: added path filters to monorepo workflows
Month 3    Budget: 7,000 gCO₂    Actual: 6,800 gCO₂   (tightening)
Month 6    Budget: 5,500 gCO₂    Actual: 5,200 gCO₂   (50% reduction from start)

A 50% reduction in six months is realistic. The fixes are not complex — they are engineering hygiene tasks that also reduce CI time and cost. The budget makes them a priority instead of a backlog item.

Plan requirements

Carbon budgets with email alerts are available on Starter and above. Merge blocking via the commit status check requires the status to be posted by EmitCI, which happens on all paid plans. The branch protection rule that causes GitHub to honour the block is a GitHub setting — no additional EmitCI plan required to configure it. Green Scheduler integration (deferring jobs to lower-carbon windows before a budget is hit) requires Team or above.

Get started free

Start measuring your CI carbon today

Connect your GitHub account in 2 minutes. Per-workflow carbon and cost estimates appear within 24 hours. No code changes required.

Install GitHub App — free for 14 days