How to set a carbon budget for your CI pipeline and block merges when it breaks
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.