Creo applicazioni web moderne e strumenti digitali personalizzati per aiutare le attività a crescere attraverso l'innovazione tecnologica. La mia passione è unire informatica ed economia per generare valore reale.
La mia passione per l'informatica è nata tra i banchi dell'Istituto Tecnico Commerciale di Maglie, dove ho scoperto il potere della programmazione e il fascino di creare soluzioni digitali. Fin da subito, ho capito che l'informatica non era solo codice, ma uno strumento straordinario per trasformare idee in realtà.
Durante gli studi superiori in Sistemi Informativi Aziendali, ho iniziato a intrecciare informatica ed economia, comprendendo come la tecnologia possa essere il motore della crescita per qualsiasi attività. Questa visione mi ha accompagnato all'Università degli Studi di Bari, dove ho conseguito la Laurea in Informatica, approfondendo le mie competenze tecniche e la mia passione per lo sviluppo software.
Oggi metto questa esperienza al servizio di imprese, professionisti e startup, creando soluzioni digitali su misura che automatizzano processi, ottimizzano risorse e aprono nuove opportunità di business. Perché la vera innovazione inizia quando la tecnologia incontra le esigenze reali delle persone.
Le Mie Competenze
Analisi Dati & Modelli Previsionali
Trasformo i dati in insights strategici con analisi approfondite e modelli predittivi per decisioni informate
Automazione Processi
Creo strumenti personalizzati che automatizzano operazioni ripetitive e liberano tempo per attività a valore aggiunto
Sistemi Custom
Sviluppo sistemi software su misura, dalle integrazioni tra piattaforme alle dashboard personalizzate
Credo fermamente che l'informatica sia lo strumento più potente per trasformare le idee in realtà e migliorare la vita delle persone.
🚀
Democratizzare la Tecnologia
La mia missione è rendere l'informatica accessibile a tutti: dalle piccole imprese locali alle startup innovative, fino ai professionisti che vogliono digitalizzare la propria attività. Ogni realtà merita di sfruttare le potenzialità del digitale.
💡
Unire Informatica ed Economia
Non è solo questione di scrivere codice: è capire come la tecnologia possa generare valore reale. Intrecciando competenze informatiche e visione economica, aiuto le attività a crescere, ottimizzare processi e raggiungere nuovi traguardi di efficienza e redditività.
🎯
Creare Soluzioni su Misura
Ogni attività è unica, e così devono esserlo le soluzioni. Sviluppo strumenti personalizzati che rispondono alle esigenze specifiche di ciascun cliente, automatizzando processi ripetitivi e liberando tempo per ciò che conta davvero: far crescere il business.
Trasforma la Tua Attività con la Tecnologia
Che tu gestisca un negozio, uno studio professionale o un'azienda, posso aiutarti a sfruttare le potenzialità dell'informatica per lavorare meglio, più velocemente e in modo più intelligente.
Il mio percorso accademico e le tecnologie che padroneggio
Certificazioni Professionali
8 certificazioni conseguite
Nuovo
Visualizza
Reinvention With Agentic AI Learning Program
Anthropic
Dicembre 2024
Nuovo
Visualizza
Agentic AI Fluency
Anthropic
Dicembre 2024
Nuovo
Visualizza
AI Fluency for Students
Anthropic
Dicembre 2024
Nuovo
Visualizza
AI Fluency: Framework and Foundations
Anthropic
Dicembre 2024
Nuovo
Visualizza
Claude with the Anthropic API
Anthropic
Dicembre 2024
Visualizza
Master SQL
RoadMap.sh
Novembre 2024
Visualizza
Oracle Certified Foundations Associate
Oracle
Ottobre 2024
Visualizza
People Leadership Credential
Connect
Settembre 2024
💻 Linguaggi & Tecnologie
☕Java
🐍Python
📜JavaScript
🅰️Angular
⚛️React
🔷TypeScript
🗄️SQL
🐘PHP
🎨CSS/SCSS
🔧Node.js
🐳Docker
🌿Git
💼
12/2024 - Presente
Custom Software Engineering Analyst
Accenture
Bari, Puglia, Italia · Ibrida
Analisi e sviluppo di sistemi informatici attraverso l'utilizzo di Java e Quarkus in Health and Public Sector. Formazione continua su tecnologie moderne per la creazione di soluzioni software personalizzate ed efficienti e sugli agenti.
💼
06/2022 - 12/2024
Analista software e Back End Developer Associate Consultant
Links Management and Technology SpA
Esperienza nell'analisi di sistemi software as-is e flussi ETL utilizzando PowerCenter. Formazione completata su Spring Boot per lo sviluppo di applicazioni backend moderne e scalabili. Sviluppatore Backend specializzato in Spring Boot, con esperienza in progettazione di database, analisi, sviluppo e testing dei task assegnati.
💼
02/2021 - 10/2021
Programmatore software
Adesso.it (prima era WebScience srl)
Esperienza nell'analisi AS-IS e TO-BE, evoluzioni SEO ed evoluzioni website per migliorare le performance e l'engagement degli utenti.
🎓
2018 - 2025
Laurea in Informatica
Università degli Studi di Bari Aldo Moro
Bachelor's degree in Computer Science, focusing on software engineering, algorithms, and modern development practices.
📚
2013 - 2018
Diploma - Sistemi Informativi Aziendali
Istituto Tecnico Commerciale di Maglie
Technical diploma specializing in Business Information Systems, combining IT knowledge with business management.
Contattami
Hai un progetto in mente? Parliamone! Compila il form qui sotto e ti risponderò al più presto.
* Campi obbligatori. I tuoi dati saranno utilizzati solo per rispondere alla tua richiesta.
Measuring the Carbon Footprint of Code: Why It Is Urgent
The ICT sector is responsible for approximately 2-4% of global CO₂ emissions,
a percentage comparable to that of the entire global aviation industry. Data centers worldwide
consumed around 460 TWh of energy in 2022 and, according to the International
Energy Agency (IEA), this figure could exceed 1,000 TWh by 2026 due to the
explosive growth of generative Artificial Intelligence. The training of GPT-3 alone required
1,287 MWh of electricity, producing approximately 502 tonnes of CO₂
equivalent — comparable to driving 112 petrol cars for an entire year.
Yet the vast majority of developers write, optimize, and deploy code without ever measuring its
real environmental impact. This is not an individual failure: it is a systemic problem of missing
tools, absent metrics, and a culture yet to be built. In this article we explore how
CodeCarbon and Cloud Carbon Footprint (CCF) close this gap,
with practical implementations, CI/CD integration, and optimizations based on real data.
What You Will Learn
Install and configure CodeCarbon with EmissionsTracker and OfflineEmissionsTracker
Use the @track_emissions decorator to automatically track Python functions
Configure advanced parameters: country_iso_code, cloud_provider, cloud_region, PUE
Integrate CodeCarbon into the web dashboard and CI/CD pipelines with GitHub Actions
Set up Cloud Carbon Footprint to monitor AWS, GCP, and Azure
Compare CodeCarbon, CCF, Green Algorithms, and the ML CO₂ Impact Calculator
Apply concrete optimizations with a case study achieving 40% emission reduction
Understand the fundamental metrics: kWh, kgCO₂eq, PUE, carbon intensity
Green Software Engineering Series (10 Articles)
#
Article
Topic
1
Principles of Green Software Engineering
GSF, SCI, 8 core principles
2
Measuring Carbon Footprint with CodeCarbon
This article — CodeCarbon, CCF, CI/CD
3
Carbon-Aware SDK and Temporal/Spatial Shifting
Shifting workloads toward green energy
4
Climatiq API and Carbon Accounting
Emissions API, LCA, Scope 1-2-3
5
Sustainable Software Patterns
Low-emission architectural patterns
6
AI Carbon Footprint and Green ML
Efficient training, pruning, distillation
7
GreenOps: FinOps for Sustainability
Optimizing cloud cost and carbon together
8
Scope 3 in the Software Pipeline
Indirect emissions, digital supply chain
9
Scope Modeling and SCI Implementation
Practical SCI calculation, Impact Framework
10
ESG, CSRD, and Digital Reporting
EU compliance, ESRS E1, disclosure
Fundamental Metrics: kWh, CO₂eq, PUE, and Carbon Intensity
Before installing any tool, it is essential to understand the metrics we will be measuring.
Every number produced by CodeCarbon or CCF carries a precise meaning that will guide
our optimization decisions.
Green Software Metrics Glossary
Metric
Unit
Description
Practical Example
Energy Consumption
kWh
Electrical energy consumed by CPU, GPU, and RAM
ResNet-50 training: 0.8 kWh
Carbon Intensity
gCO₂eq/kWh
Emissions per unit of energy from the local electricity mix
France: ~56 g/kWh, Poland: ~720 g/kWh
CO₂ Emissions
kgCO₂eq
Total emissions = Energy × Carbon Intensity
0.8 kWh × 0.056 kg/kWh = 0.045 kgCO₂eq
PUE
ratio
Power Usage Effectiveness = Total Facility Power / IT Load
Google: 1.10, industry average: 1.58
SCI Score
gCO₂eq/R
Software Carbon Intensity per functional unit (R)
42 gCO₂eq per 1,000 API calls
Carbon Avoided
kgCO₂eq
Emissions avoided compared to a reference baseline
Batch processing vs. real-time: -35%
The central formula used by CodeCarbon is:
CO₂ Emissions (kgCO₂eq) = Energy Consumed (kWh) × Carbon Intensity (kgCO₂eq/kWh)
Where:
Energy Consumed = (CPU Power + GPU Power + RAM Power) × Duration / 1000
Carbon Intensity = Regional factor (e.g. 0.056 for France, 0.720 for Poland)
Example:
CPU: 65W, GPU: 200W, RAM: 8W, duration: 2 hours
Energy = (65 + 200 + 8) × 2 / 1000 = 0.546 kWh
CO₂ (France) = 0.546 × 0.056 = 0.031 kgCO₂eq (31 g)
CO₂ (Poland) = 0.546 × 0.720 = 0.393 kgCO₂eq (393 g)
Difference: 12.7x for the same workload, simply due to region choice!
CodeCarbon: Installation and Configuration
CodeCarbon is an open-source Python package originally developed by the
Université de Montréal (Mila), now maintained by the non-profit organization
Code Carbon based in France. The project has over 1,700 GitHub stars
and 249 forks, with contributions from Mila, BCG GAMMA, and Comet ML.
What distinguishes CodeCarbon from other tools is its direct hardware measurement:
instead of theoretical estimates, it reads real CPU, GPU, and RAM sensors to calculate actual
energy consumption, then multiplies by the carbon intensity factor of the geographic region
where the code is running.
Basic Installation
# Standard installation
pip install codecarbon
# With optional dependencies for local dashboard
pip install codecarbon[viz]
# For conda environments
conda install -c conda-forge codecarbon
# Verify installation and available hardware
codecarbon detect
# Typical output:
# [codecarbon] CPU Model: Intel Core i7-12700K
# [codecarbon] GPU: NVIDIA RTX 4080 (VRAM: 16384 MB)
# [codecarbon] RAM: 32768 MB
# [codecarbon] OS: Linux
# [codecarbon] Python: 3.11.0
First Use: The Context Manager
The simplest way to get started is to use EmissionsTracker
as a Python context manager. CodeCarbon automatically writes results to an
emissions.csv file in the current directory.
from codecarbon import EmissionsTracker
import time
# Using as a context manager
with EmissionsTracker() as tracker:
# Your computational code here
print("Starting computation...")
time.sleep(2) # Simulate processing
result = sum(i ** 2 for i in range(10_000_000))
print(f"Result: {result}")
# After the 'with' block, the tracker has already written emissions.csv
# and printed a summary:
# [codecarbon] Energy consumed: 0.000123 kWh
# [codecarbon] Emissions: 0.0000689 kg CO2eq
# [codecarbon] Equivalent: Driving 0.00036 km with a petrol car
Explicit Usage with Start/Stop
from codecarbon import EmissionsTracker
tracker = EmissionsTracker(
project_name="my-ml-project",
output_dir="./carbon_logs",
output_file="emissions_results.csv",
log_level="WARNING" # Reduces verbose output
)
tracker.start()
try:
# Phase 1: data preprocessing
print("Preprocessing...")
data = preprocess_dataset()
# Intermediate flush - useful for long training runs
emissions_so_far = tracker.flush()
print(f"Preprocessing emissions: {emissions_so_far:.6f} kgCO2eq")
# Phase 2: model training
print("Training...")
model = train_model(data)
except Exception as e:
print(f"Error: {e}")
raise
finally:
# stop() returns total emissions in kgCO2eq
final_emissions = tracker.stop()
print(f"\\nTotal emissions: {final_emissions:.6f} kgCO2eq")
print(f"Equivalent to: {final_emissions * 1000:.2f} gCO2eq")
def preprocess_dataset():
"""Placeholder function for preprocessing."""
import time
time.sleep(1)
return list(range(1000))
def train_model(data):
"""Placeholder function for training."""
import time
time.sleep(2)
return {"accuracy": 0.95}
The @track_emissions Decorator: Automatic Function Tracking
The most elegant way to integrate CodeCarbon into existing code is the
@track_emissions decorator. With a single line, every call to the function
is tracked automatically, without modifying the internal logic.
Basic Decorator
from codecarbon import track_emissions
import numpy as np
from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
@track_emissions(
project_name="fraud-classifier",
output_dir="./carbon_reports",
country_iso_code="ITA", # Italy
log_level="WARNING"
)
def train_fraud_detector(n_samples: int = 100_000) -> dict:
"""
Trains a Random Forest for fraud detection.
Emissions are recorded automatically.
"""
print(f"Generating dataset: {n_samples} samples...")
X, y = make_classification(
n_samples=n_samples,
n_features=30,
n_informative=15,
n_redundant=5,
random_state=42
)
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42
)
print("Training Random Forest...")
clf = RandomForestClassifier(
n_estimators=200,
max_depth=15,
n_jobs=-1, # Uses all available cores
random_state=42
)
clf.fit(X_train, y_train)
accuracy = clf.score(X_test, y_test)
return {"accuracy": accuracy, "n_estimators": 200}
if __name__ == "__main__":
# The function is called normally
# CodeCarbon tracks emissions automatically
result = train_fraud_detector(n_samples=50_000)
print(f"Accuracy: {result['accuracy']:.4f}")
# emissions.csv is created automatically in ./carbon_reports/
Decorator with Offline Mode
In environments without internet access (HPC clusters, isolated VMs, secure production
environments), use offline=True with country_iso_code to manually
specify the carbon intensity factor.
from codecarbon import track_emissions, OfflineEmissionsTracker
# Offline decorator with country specified manually
@track_emissions(
offline=True,
country_iso_code="SWE", # Sweden - very clean grid (~13 gCO2eq/kWh)
project_name="batch-inference-nordics",
output_dir="/var/log/carbon",
output_file="inference_emissions.csv",
measure_power_secs=10, # Sample every 10 seconds (default: 15)
log_level="ERROR"
)
def batch_inference_pipeline(model_path: str, data_path: str) -> list:
"""Batch inference on HPC server in Sweden."""
import time
import random
print(f"Loading model from {model_path}...")
time.sleep(0.5)
print(f"Reading data from {data_path}...")
# Simulate 10k inferences
results = []
for i in range(10_000):
# Simulate inference
prediction = random.random()
results.append({"id": i, "score": prediction})
print(f"Completed {len(results)} inferences")
return results
# OfflineEmissionsTracker as an explicit alternative
def run_with_explicit_offline_tracker():
"""Example using OfflineEmissionsTracker for manual control."""
tracker = OfflineEmissionsTracker(
country_iso_code="DEU", # Germany
project_name="preprocessing-de",
output_dir="./emissions"
)
tracker.start()
try:
# Simulate processing
import time
time.sleep(3)
result = {"processed_records": 1_000_000}
finally:
emissions = tracker.stop()
print(f"Germany emissions: {emissions * 1000:.2f} gCO2eq")
return result
Advanced Configuration: Cloud Providers, Regions, and Config Files
CodeCarbon supports configuration via a .codecarbon.config file in the
project directory, allowing you to centralize parameters and use advanced features
such as cloud tracking and uploading data to the web dashboard.
The .codecarbon.config Configuration File
[codecarbon]
# Project identifiers
project_name = fraud-detection-prod
experiment_id = a1b2c3d4-e5f6-7890-abcd-ef1234567890
# Output modes
save_to_api = True # Upload to the CodeCarbon dashboard
save_to_file = True # Also save a local CSV
output_dir = ./carbon_logs
output_file = emissions.csv
# Localization - use country_iso_code for offline
# or specify cloud_provider + cloud_region for cloud
cloud_provider = aws # aws | gcp | azure
cloud_region = eu-west-1 # Specific cloud region
# Or for on-premise:
# country_iso_code = ITA # ISO-3166-1 alpha-3 code
# Performance
measure_power_secs = 15 # Sampling interval (seconds)
tracking_mode = machine # machine | process | car
# Logging
log_level = WARNING # DEBUG | INFO | WARNING | ERROR | CRITICAL
# Custom PUE for proprietary data center
# (default: uses regional average values)
# pue = 1.15
Configuration for Cloud Providers
from codecarbon import EmissionsTracker
# AWS - Training on SageMaker in Ireland (eu-west-1)
tracker_aws = EmissionsTracker(
project_name="sagemaker-training",
cloud_provider="aws",
cloud_region="eu-west-1", # Ireland - average energy mix
save_to_file=True,
output_dir="./carbon"
)
# GCP - Training on Vertex AI in Finland (europe-north1)
# Finland: very high renewable mix, ~12 gCO2eq/kWh
tracker_gcp = EmissionsTracker(
project_name="vertex-ai-training",
cloud_provider="gcp",
cloud_region="europe-north1", # Finland - green grid
save_to_file=True,
output_dir="./carbon"
)
# Azure - Training in Sweden (swedencentral)
# Sweden: ~13 gCO2eq/kWh, hydroelectric + nuclear
tracker_azure = EmissionsTracker(
project_name="azure-ml-training",
cloud_provider="azure",
cloud_region="swedencentral",
save_to_file=True,
output_dir="./carbon"
)
# Carbon intensity table by cloud region (approximate 2025 values)
CARBON_INTENSITY_BY_REGION = {
# AWS
"aws/us-east-1": 0.386, # Virginia, USA (gCO2eq/kWh -> kg)
"aws/eu-west-1": 0.316, # Ireland
"aws/eu-north-1": 0.013, # Stockholm, Sweden
"aws/ap-southeast-2": 0.610, # Sydney, Australia
# GCP
"gcp/europe-north1": 0.012, # Finland
"gcp/us-central1": 0.497, # Iowa, USA
"gcp/europe-west1": 0.087, # Belgium
# Azure
"azure/swedencentral": 0.013, # Sweden
"azure/northeurope": 0.312, # Ireland
"azure/eastus": 0.386, # Virginia
}
def calculate_region_savings(
energy_kwh: float,
from_region: str,
to_region: str
) -> dict:
"""
Calculates emission savings from shifting a workload
from one cloud region to another.
"""
co2_from = energy_kwh * CARBON_INTENSITY_BY_REGION.get(from_region, 0.4)
co2_to = energy_kwh * CARBON_INTENSITY_BY_REGION.get(to_region, 0.4)
savings = co2_from - co2_to
percentage = (savings / co2_from * 100) if co2_from > 0 else 0
return {
"energy_kwh": energy_kwh,
"original_emissions_kg": co2_from,
"optimized_emissions_kg": co2_to,
"savings_kg": savings,
"savings_percentage": percentage,
"annual_savings_kg": savings * 365 # if run every day
}
# Example: daily training consuming 50 kWh
analysis = calculate_region_savings(
energy_kwh=50,
from_region="aws/us-east-1",
to_region="aws/eu-north-1"
)
print(f"Savings: {analysis['savings_percentage']:.1f}%")
print(f"CO2 avoided/year: {analysis['annual_savings_kg']:.1f} kg")
# Output:
# Savings: 96.6%
# CO2 avoided/year: 6,994.5 kg
CodeCarbon Web Dashboard: Visualizing Emissions
CodeCarbon offers a web dashboard hosted at dashboard.codecarbon.io that
allows you to visualize and compare emissions over time across multiple experiments.
The dashboard is free and requires only a registered account.
Dashboard Setup and API Integration
# Step 1: Register an account at https://dashboard.codecarbon.io
# Step 2: Create a project and obtain an experiment_id
# Step 3: Configure CodeCarbon to upload data
from codecarbon import EmissionsTracker
import os
# Use an environment variable for the experiment_id (never hardcode!)
EXPERIMENT_ID = os.environ.get("CODECARBON_EXPERIMENT_ID")
tracker = EmissionsTracker(
project_name="production-ml-pipeline",
experiment_id=EXPERIMENT_ID,
save_to_api=True, # Enable upload to the dashboard
save_to_file=True, # Also keep a local copy
output_dir="./carbon_logs",
log_level="WARNING"
)
# The .codecarbon.config file (alternative to environment variables):
# [codecarbon]
# save_to_api = True
# experiment_id =
#123;CODECARBON_EXPERIMENT_ID}
# api_endpoint = https://api.codecarbon.io # Default
# Tracking with periodic flush for long runs (e.g., 24h training)
tracker.start()
CHECKPOINT_INTERVAL = 100 # flush every 100 epochs
for epoch in range(1, 501):
# Simulate training epoch
train_one_epoch(epoch)
if epoch % CHECKPOINT_INTERVAL == 0:
# flush() sends intermediate data to the dashboard
intermediate = tracker.flush()
print(f"Epoch {epoch} - Emissions: {intermediate:.4f} kgCO2eq")
final_emissions = tracker.stop()
print(f"Training complete. Total emissions: {final_emissions:.4f} kgCO2eq")
def train_one_epoch(epoch: int):
"""Placeholder for training epoch."""
import time
time.sleep(0.01) # Simulate processing
Local Dashboard with codecarbon-viz
# Install visualization
pip install codecarbon[viz]
# Launch local dashboard (after accumulating data in emissions.csv)
codecarbon-viz --data ./carbon_logs/emissions.csv
# The local dashboard shows:
# - Time series chart of emissions per experiment
# - Comparison across runs
# - Breakdown by project
# - Communicative equivalents (km by car, flights, trees)
# Alternatively: generate a static HTML report
from codecarbon.viz.report import generate_report
generate_report(
data_path="./carbon_logs/emissions.csv",
output_path="./carbon_report.html"
)
While CodeCarbon tracks emissions of running code, Cloud Carbon
Footprint (CCF) operates at a different level: it analyzes cloud billing
data (AWS Cost Explorer, GCP Billing, Azure Cost Management) and estimates the
emissions of all of an organization's cloud infrastructure — servers, storage,
databases, networking, and managed services.
CCF was originally developed by Thoughtworks and is open source (MIT License).
In 2025, with the project in a reduced maintenance mode, Climatiq and other commercial
tools are emerging as alternatives for enterprise environments.
CCF Architecture
Cloud Carbon Footprint Components
Component
Function
Technology
API Server
Aggregates data from cloud providers and calculates emissions
import requests
from datetime import datetime, timedelta
import json
CCF_API_URL = "http://localhost:4000"
def get_cloud_emissions(
days_back: int = 30,
granularity: str = "daily"
) -> dict:
"""
Queries the CCF API to retrieve cloud emissions for the last N days.
Args:
days_back: How many days of data to retrieve
granularity: 'daily' | 'monthly' | 'weekly'
Returns:
Dictionary with emissions broken down by provider, service, and region
"""
end_date = datetime.utcnow()
start_date = end_date - timedelta(days=days_back)
params = {
"startDate": start_date.strftime("%Y-%m-%d"),
"endDate": end_date.strftime("%Y-%m-%d"),
"groupBy": granularity,
"ignoreCache": "false"
}
try:
response = requests.get(
f"{CCF_API_URL}/api/footprint",
params=params,
timeout=120 # CCF can be slow on large datasets
)
response.raise_for_status()
data = response.json()
# Aggregate by cloud provider
summary = {
"period": f"{params['startDate']} -> {params['endDate']}",
"by_provider": {},
"total_co2_mt": 0,
"total_kwh": 0
}
for entry in data:
provider = entry.get("cloudProvider", "unknown")
if provider not in summary["by_provider"]:
summary["by_provider"][provider] = {
"co2_mt": 0,
"kwh": 0,
"cost_usd": 0
}
summary["by_provider"][provider]["co2_mt"] += entry.get("co2e", 0)
summary["by_provider"][provider]["kwh"] += entry.get("kilowattHours", 0)
summary["by_provider"][provider]["cost_usd"] += entry.get("cost", 0)
summary["total_co2_mt"] += entry.get("co2e", 0)
summary["total_kwh"] += entry.get("kilowattHours", 0)
return summary
except requests.exceptions.RequestException as e:
print(f"CCF connection error: {e}")
raise
# Usage
emissions = get_cloud_emissions(days_back=30)
print(json.dumps(emissions, indent=2))
# Example output:
# {
# "period": "2025-02-09 -> 2025-03-09",
# "by_provider": {
# "AWS": { "co2_mt": 1.23, "kwh": 4521, "cost_usd": 12450 },
# "GCP": { "co2_mt": 0.18, "kwh": 892, "cost_usd": 3210 },
# "Azure": { "co2_mt": 0.67, "kwh": 2103, "cost_usd": 7890 }
# },
# "total_co2_mt": 2.08,
# "total_kwh": 7516
# }
Tool Comparison: CodeCarbon vs. CCF vs. Green Algorithms vs. ML CO₂ Impact
The market for software emission measurement tools has grown rapidly. Choosing the right
tool depends on context: code type, scale, budget, reporting requirements, and the required
level of accuracy.
Comparative Tool Matrix
Criterion
CodeCarbon
Cloud Carbon Footprint
Green Algorithms
ML CO₂ Impact
Type
Python runtime library
Multi-cloud billing app
Web calculator
Web/API calculator
Measurement
Direct (hardware sensors)
Indirect (cloud bills)
Parametric estimate
Parametric estimate
Accuracy
High (±10-20%)
Medium (±30%)
Low-Medium (±50-150%)
Low (2.42x ratio)
CI/CD Integration
Native (decorator, API)
Partial (HTTP API)
No
No
Cloud Scope
Single execution
Entire infrastructure
Single algorithm
ML training
Cost
Free (open source)
Free (open source)
Free (web)
Free (web)
Offline
Yes (OfflineTracker)
No
Yes (web form)
Yes (web form)
Dashboard
Web + local
Web (React)
No
No
Best Use Case
Dev/research tracking
CFO/Sustainability team
Scientific paper
ML paper disclosure
When to Use Which Tool
Tool Selection Guide
CodeCarbon: You are developing ML models or Python pipelines and want to measure the impact of specific functions in real time. Ideal for researchers and data scientists.
Cloud Carbon Footprint: You are a cloud architect or sustainability officer who wants an aggregated view of all organizational emissions across AWS/GCP/Azure.
Green Algorithms: You are writing a scientific paper and need a standardized emission figure for the "Broader Impact" section.
ML CO₂ Impact Calculator: You want a quick comparison between different hardware/region choices before launching an expensive training run.
Climatiq API: You need automated carbon accounting in production with regular updates to emission factors (article #4 of this series).
CI/CD Integration: GitHub Actions for Carbon Budget
Integrating emission tracking into CI/CD transforms sustainability from an occasional metric
into a non-functional requirement of software, analogous to performance tests
or code coverage. We can define a carbon budget and fail the build if it is exceeded.
# scripts/carbon_benchmark.py
"""
Benchmark script for CI/CD.
Measures emissions of critical project operations.
"""
import sys
import os
from codecarbon import EmissionsTracker
from typing import Callable
def run_benchmark(
name: str,
func: Callable,
*args,
**kwargs
) -> float:
"""
Runs a function with emission tracking.
Returns emissions in kgCO2eq.
"""
tracker = EmissionsTracker(
project_name=f"ci-benchmark-{name}",
output_file="emissions.csv",
output_dir=".",
log_level="ERROR",
# In CI we use offline mode with USA (GitHub runner)
country_iso_code=os.environ.get("CODECARBON_COUNTRY_ISO_CODE", "USA")
)
tracker.start()
try:
result = func(*args, **kwargs)
emissions = tracker.stop()
print(f"[CARBON] {name}: {emissions * 1000:.4f} gCO2eq")
return emissions
except Exception as e:
tracker.stop()
print(f"[CARBON] {name} FAILED: {e}", file=sys.stderr)
raise
def benchmark_data_processing():
"""Benchmark: dataset processing."""
import numpy as np
data = np.random.randn(100_000, 50)
result = np.dot(data.T, data)
return result.shape
def benchmark_model_inference():
"""Benchmark: model inference."""
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.datasets import make_classification
import numpy as np
X, y = make_classification(n_samples=10_000, n_features=20)
clf = GradientBoostingClassifier(n_estimators=50)
clf.fit(X, y)
X_test = np.random.randn(1_000, 20)
predictions = clf.predict(X_test)
return predictions
def benchmark_api_simulation():
"""Benchmark: simulate 10k API requests."""
import json
results = []
for i in range(10_000):
payload = {"id": i, "value": i * 3.14}
serialized = json.dumps(payload)
deserialized = json.loads(serialized)
results.append(deserialized["value"])
return sum(results)
if __name__ == "__main__":
print("=== Carbon Benchmark Suite ===")
total_emissions = 0
benchmarks = [
("data_processing", benchmark_data_processing),
("model_inference", benchmark_model_inference),
("api_simulation", benchmark_api_simulation),
]
for bench_name, bench_func in benchmarks:
emissions = run_benchmark(bench_name, bench_func)
total_emissions += emissions
print(f"\\n[CARBON] Total: {total_emissions * 1000:.4f} gCO2eq")
print(f"[CARBON] Output written to: emissions.csv")
Carbon Budget Check Script
# scripts/check_carbon_budget.py
"""
Checks whether measured emissions respect the defined budget.
Returns exit code 1 if the budget is exceeded (causes build failure).
"""
import argparse
import sys
import csv
from pathlib import Path
def read_total_emissions(csv_path: str) -> float:
"""Reads total emissions from the CodeCarbon CSV."""
path = Path(csv_path)
if not path.exists():
print(f"ERROR: File not found: {csv_path}", file=sys.stderr)
sys.exit(2)
total_emissions = 0.0
with open(csv_path, newline="") as f:
reader = csv.DictReader(f)
for row in reader:
try:
total_emissions += float(row.get("emissions", 0))
except ValueError:
pass # Skip malformed rows
return total_emissions
def main():
parser = argparse.ArgumentParser(
description="Check carbon budget for CI/CD"
)
parser.add_argument(
"--csv", required=True,
help="Path to the CodeCarbon emissions.csv file"
)
parser.add_argument(
"--budget-kg", type=float, required=True,
help="Maximum budget in kgCO2eq"
)
parser.add_argument(
"--fail-on-exceed", action="store_true",
help="Returns exit code 1 if budget is exceeded"
)
parser.add_argument(
"--warn-threshold", type=float, default=0.8,
help="Warning if emissions exceed X%% of budget (default: 80%%)"
)
args = parser.parse_args()
emissions = read_total_emissions(args.csv)
budget = args.budget_kg
percentage = (emissions / budget * 100) if budget > 0 else 0
print("\\n=== Carbon Budget Report ===")
print(f"Measured emissions: {emissions * 1000:.4f} gCO2eq")
print(f"Defined budget: {budget * 1000:.4f} gCO2eq")
print(f"Budget utilization: {percentage:.1f}%")
if emissions > budget:
print(f"\\nFAILURE: Budget exceeded by {(emissions - budget) * 1000:.4f} gCO2eq!")
if args.fail_on_exceed:
sys.exit(1)
elif percentage >= args.warn_threshold * 100:
print(f"\\nWARNING: Emissions at {percentage:.1f}% of budget.")
print("Consider optimizations before the budget is exceeded.")
else:
print(f"\\nOK: Budget respected ({percentage:.1f}% used)")
sys.exit(0)
if __name__ == "__main__":
main()
Case Study 1: Achieving a 40% Emission Reduction in ML Training
This case study shows a complete optimization workflow: we measure the emissions of a
baseline training run, identify bottlenecks, and apply progressive optimizations,
reaching a 40% reduction in emissions while maintaining the same model
accuracy.
# case_study_ml_optimization.py
"""
Case Study: Emission optimization for an image classifier training run
Scenario: ResNet-like training on a custom dataset of 50k images
Hardware: NVIDIA RTX 4080, Intel i9-13900K
Region: AWS us-east-1 (Virginia, 386 gCO2eq/kWh)
"""
import numpy as np
from codecarbon import EmissionsTracker
# ========= BASELINE: Unoptimized Training =========
def train_baseline(X_train, y_train, X_val, y_val):
"""
Unoptimized training:
- No early stopping
- Small batch size (16)
- All default hyperparameters
- No mixed precision
"""
from sklearn.neural_network import MLPClassifier
clf = MLPClassifier(
hidden_layer_sizes=(512, 256, 128),
max_iter=200, # Full training without early stop
batch_size=16, # Suboptimal batch size
random_state=42,
verbose=False
)
clf.fit(X_train, y_train)
return clf.score(X_val, y_val), clf
def train_optimized(X_train, y_train, X_val, y_val):
"""
Optimized training:
- Early stopping (saves ~30% emissions)
- Larger batch size (fewer updates, more efficient)
- n_iter_no_change for patience
- Leaner architecture (light distillation)
"""
from sklearn.neural_network import MLPClassifier
clf = MLPClassifier(
hidden_layer_sizes=(256, 128), # Reduced architecture (-50% params)
max_iter=200,
batch_size=256, # 16x larger batch size
early_stopping=True, # Stop if val_loss does not improve
validation_fraction=0.1,
n_iter_no_change=10, # Patience = 10 epochs
random_state=42,
verbose=False
)
clf.fit(X_train, y_train)
return clf.score(X_val, y_val), clf
# Generate synthetic dataset for the example
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
X, y = make_classification(
n_samples=10_000,
n_features=100,
n_informative=50,
random_state=42
)
X_train, X_val, y_train, y_val = train_test_split(
X, y, test_size=0.2, random_state=42
)
results = {}
# ---- Measure Baseline ----
print("\\n=== BASELINE: Unoptimized Training ===")
with EmissionsTracker(
project_name="baseline-training",
country_iso_code="USA",
log_level="ERROR"
) as tracker:
acc_baseline, _ = train_baseline(X_train, y_train, X_val, y_val)
emissions_baseline = tracker.final_emissions
results["baseline"] = {
"accuracy": acc_baseline,
"emissions_kg": emissions_baseline,
"emissions_g": emissions_baseline * 1000
}
print(f"Accuracy: {acc_baseline:.4f}")
print(f"Emissions: {emissions_baseline * 1000:.4f} gCO2eq")
# ---- Measure Optimized ----
print("\\n=== OPTIMIZED: Training with early stopping and optimized batch ===")
with EmissionsTracker(
project_name="optimized-training",
country_iso_code="USA",
log_level="ERROR"
) as tracker:
acc_optimized, _ = train_optimized(X_train, y_train, X_val, y_val)
emissions_optimized = tracker.final_emissions
results["optimized"] = {
"accuracy": acc_optimized,
"emissions_kg": emissions_optimized,
"emissions_g": emissions_optimized * 1000
}
print(f"Accuracy: {acc_optimized:.4f}")
print(f"Emissions: {emissions_optimized * 1000:.4f} gCO2eq")
# ---- Comparative Report ----
print("\\n=== COMPARATIVE REPORT ===")
reduction = (
1 - results["optimized"]["emissions_kg"] /
results["baseline"]["emissions_kg"]
) * 100
delta_acc = (
results["optimized"]["accuracy"] -
results["baseline"]["accuracy"]
) * 100
print(f"Emission reduction: {reduction:.1f}%")
print(f"Accuracy delta: {delta_acc:+.2f} percentage points")
print(f"Tradeoff: {reduction:.1f}% less CO2 with {abs(delta_acc):.2f}pp {'worse' if delta_acc < 0 else 'better'}")
# If run 365 times per year:
annual_savings = (
results["baseline"]["emissions_kg"] -
results["optimized"]["emissions_kg"]
) * 365
print(f"\\nAnnual savings (1 run/day): {annual_savings:.3f} kgCO2eq")
print(f"Equivalent to: {annual_savings * 6.28:.1f} km by petrol car")
Case Study 2: Cloud Region Comparison — US-East vs. EU-West vs. Nordics
One of the most impactful and least invasive optimizations is simply
choosing the right cloud region. For the same workload and often similar
cost, moving from Virginia to Stockholm can reduce emissions by up to 96%.
# case_study_cloud_regions.py
"""
Cost-emission analysis for ML workloads across different cloud regions.
Data based on 2025 carbon intensity (electricity maps + provider reports).
"""
from dataclasses import dataclass
from typing import Optional
import json
@dataclass
class CloudRegion:
provider: str
region_id: str
region_name: str
country: str
carbon_intensity_g_kwh: float # gCO2eq/kWh
pue: float # Power Usage Effectiveness
renewable_pct: float # % renewable energy
compute_cost_usd_hr: float # Equivalent p3.2xlarge cost
# Cloud region data (2025 approximations)
REGIONS = [
CloudRegion("AWS", "us-east-1", "N. Virginia", "USA", 386, 1.15, 10, 3.06),
CloudRegion("AWS", "us-west-2", "Oregon", "USA", 136, 1.12, 42, 3.06),
CloudRegion("AWS", "eu-west-1", "Ireland", "IRL", 316, 1.13, 33, 3.37),
CloudRegion("AWS", "eu-west-3", "Paris", "FRA", 56, 1.14, 23, 3.59),
CloudRegion("AWS", "eu-north-1", "Stockholm", "SWE", 13, 1.08, 95, 3.37),
CloudRegion("GCP", "us-central1", "Iowa", "USA", 497, 1.11, 48, 2.88),
CloudRegion("GCP", "europe-west1", "Belgium", "BEL", 87, 1.09, 82, 3.11),
CloudRegion("GCP", "europe-north1", "Finland", "FIN", 12, 1.07, 98, 3.11),
CloudRegion("AZR", "eastus", "Virginia", "USA", 386, 1.16, 10, 3.06),
CloudRegion("AZR", "swedencentral", "Sweden Central", "SWE", 13, 1.08, 95, 3.26),
CloudRegion("AZR", "northeurope", "Ireland", "IRL", 312, 1.14, 33, 3.45),
]
def calculate_region_emissions(
region: CloudRegion,
energy_kwh: float
) -> dict:
"""
Calculates emissions and costs for an X-kWh workload in a region.
Note: PUE increases total energy consumed by the data center,
but does not proportionally increase per-tenant emissions in cloud
(tenants pay for IT energy, not total facility energy).
For simplicity, we include PUE as an overhead factor.
"""
total_energy = energy_kwh * region.pue # Data center overhead
co2_kg = total_energy * region.carbon_intensity_g_kwh / 1000
co2_g = co2_kg * 1000
# Estimated cost (hours needed to consume X kWh)
# Assuming GPU at ~300W = 0.3 kW
estimated_hours = energy_kwh / 0.3
cost_usd = estimated_hours * region.compute_cost_usd_hr
return {
"region": f"{region.provider}/{region.region_id}",
"name": region.region_name,
"country": region.country,
"carbon_intensity": region.carbon_intensity_g_kwh,
"pue": region.pue,
"renewable_pct": region.renewable_pct,
"co2_g": round(co2_g, 2),
"co2_kg": round(co2_kg, 4),
"cost_usd": round(cost_usd, 2),
"co2_per_usd": round(co2_g / cost_usd, 2) if cost_usd > 0 else 0
}
def generate_region_report(energy_kwh: float = 10.0) -> None:
"""
Generates a comparative report for a workload of N kWh.
"""
print(f"\\n=== Cloud Region Analysis for Workload: {energy_kwh} kWh ===")
print(f"(Equivalent to ~{energy_kwh / 0.3:.0f} hours of GPU at 300W)\\n")
results = [
calculate_region_emissions(r, energy_kwh)
for r in REGIONS
]
# Sort by ascending emissions
sorted_results = sorted(results, key=lambda x: x["co2_g"])
print(f"{'Region':<30} {'gCO2eq':<12} {'USD':<10} {'Renew.':<10} {'PUE':<6}")
print("-" * 75)
for r in sorted_results:
tag = " <-- OPTIMAL" if r == sorted_results[0] else ""
tag = " <-- WORST" if r == sorted_results[-1] else tag
print(
f"{r['region']:<30} "
f"{r['co2_g']:<12.1f} "
f"#123;r['cost_usd']:<9.2f} "
f"{r['renewable_pct']:<9.0f}% "
f"{r['pue']:<6}"
f"{tag}"
)
print()
best = sorted_results[0]
worst = sorted_results[-1]
print(f"Best: {best['region']} ({best['co2_g']} gCO2eq)")
print(f"Worst: {worst['region']} ({worst['co2_g']} gCO2eq)")
ratio = worst["co2_g"] / best["co2_g"]
print(f"Ratio: {ratio:.1f}x more polluting")
print(f"Cost delta: #123;abs(best['cost_usd'] - worst['cost_usd']):.2f} "
f"({((best['cost_usd'] / worst['cost_usd']) - 1) * 100:+.1f}%)")
generate_region_report(energy_kwh=10)
# Example output:
# Region gCO2eq USD Renew. PUE
# ---------------------------------------------------------------------------
# GCP/europe-north1 1.3 96.00 98% 1.07 <-- OPTIMAL
# AWS/eu-north-1 1.4 112.00 95% 1.08
# AZR/swedencentral 1.4 108.67 95% 1.08
# GCP/europe-west1 9.5 103.67 82% 1.09
# AWS/us-west-2 15.3 102.00 42% 1.12
# AWS/eu-west-3 6.4 119.67 23% 1.14 (France, nuclear)
# ...
# GCP/us-central1 55.1 96.00 48% 1.11 <-- WORST
# Ratio: 42.4x more polluting
Warning: Carbon Intensity Is Not Stable
Carbon intensity values vary throughout the day and across seasons. Sweden in summer
(abundant solar) may have an even lower intensity. Virginia in winter (high heating demand,
more gas) may be worse than expected. Tools like the Carbon Aware SDK
(article #3 of this series) enable temporal shifting: waiting for greener energy
hours before launching intensive training runs.
Best Practices and Anti-Patterns
Best Practices
Carbon-Aware Development Checklist
Measure before optimizing: Establish a baseline with CodeCarbon before any optimization. Do not assume where the bottlenecks are.
Use offline tracker in CI/CD: OfflineEmissionsTracker with country_iso_code is more reliable in automated environments where IP geolocation might fail.
Define a carbon budget per project: Analogously to performance budgets (LCP < 2.5s), set measurable and verifiable emission budgets that are enforced in CI.
Record contextual metadata: Always save alongside emissions: number of records processed, model accuracy, code version. Without context, absolute emission figures say nothing.
Prefer batch processing: Accumulating data and processing it in batches during green-energy hours is almost always more efficient than continuous real-time processing.
Optimize architecture first: Early stopping, leaner architectures (distillation, pruning), and efficient hyperparameter search reduce emissions far more than any hardware optimization.
Choose the cloud region for its emissions: For batch workloads that are not time-sensitive, region choice is often the single most impactful optimization factor (up to 42x).
Use mixed precision training: FP16/BF16 reduces memory and compute, lowering emissions by 30-50% for training on modern GPUs.
Anti-Patterns to Avoid
Common Anti-Patterns in Carbon Tracking
Blindly trusting absolute values: Parametric calculators such as
Green Algorithms and ML CO₂ Impact can have errors of up to 2.4x compared to
real measurements. Use them for comparisons, not ESG reporting.
Ignoring inference emissions: Training is a one-time event.
Inference in production can exceed training emissions within a few weeks if request
volume is high (GPT-4: millions of queries per day).
Carbon washing with offsets: Buying offsets to "neutralize" emissions
without optimizing the code is considered greenwashing. The priority is always to
reduce first; offsets are a last resort.
Tracking without acting: Emission tracking has value only if it
generates concrete optimization actions. Measuring and ignoring the data is a
purely cosmetic exercise.
Excessive tracker overhead: measure_power_secs=1
(sampling every second) for short operations can add significant overhead.
Use 15-30 second intervals for long-running operations.
Not accounting for PUE: Code emissions include the overhead of
the data center (cooling, UPS, etc.). A PUE of 1.58 (industry average) vs. 1.08
(Sweden) makes a 46% difference in real emissions.
Advanced Pattern: Carbon-Aware Scheduler
# patterns/carbon_aware_scheduler.py
"""
Carbon-Aware Pattern: defer heavy workloads to green-energy hours.
Integrates with the Electricity Maps API (formerly Tomorrow.io) for real-time data.
"""
import time
import requests
from datetime import datetime
from functools import wraps
from typing import Callable, Optional
ELECTRICITY_MAPS_API = "https://api.electricitymap.org/v3"
CARBON_INTENSITY_THRESHOLD = 200 # gCO2eq/kWh - threshold for "green energy"
MAX_WAIT_HOURS = 12 # Do not wait more than 12 hours
def get_carbon_intensity(zone: str, api_key: str) -> Optional[float]:
"""
Retrieve the current carbon intensity for a geographic zone.
Zone examples: IT (Italy), SE (Sweden), FR (France), US-NY (New York)
"""
try:
response = requests.get(
f"{ELECTRICITY_MAPS_API}/carbon-intensity/latest",
params={"zone": zone},
headers={"auth-token": api_key},
timeout=10
)
response.raise_for_status()
data = response.json()
return data.get("carbonIntensity")
except requests.RequestException as e:
print(f"Unable to retrieve carbon intensity: {e}")
return None
def carbon_aware(
zone: str = "IT",
api_key: str = "",
threshold_g_kwh: float = CARBON_INTENSITY_THRESHOLD,
check_interval_minutes: int = 30
):
"""
Decorator that delays execution until carbon intensity
falls below the defined threshold.
"""
def decorator(func: Callable) -> Callable:
@wraps(func)
def wrapper(*args, **kwargs):
waited_minutes = 0
max_wait_minutes = MAX_WAIT_HOURS * 60
while waited_minutes < max_wait_minutes:
intensity = get_carbon_intensity(zone, api_key)
if intensity is None:
print("Carbon intensity unavailable, proceeding anyway.")
break
print(
f"[{datetime.now().strftime('%H:%M')}] "
f"Carbon intensity: {intensity:.0f} gCO2eq/kWh "
f"(threshold: {threshold_g_kwh})"
)
if intensity <= threshold_g_kwh:
print(f"Green energy! Starting {func.__name__}...")
break
print(f"Waiting {check_interval_minutes} minutes...")
time.sleep(check_interval_minutes * 60)
waited_minutes += check_interval_minutes
if waited_minutes >= max_wait_minutes:
print(f"Timeout reached ({MAX_WAIT_HOURS}h). Proceeding anyway.")
return func(*args, **kwargs)
return wrapper
return decorator
# Using the carbon-aware decorator
@carbon_aware(
zone="IT",
api_key="your-electricity-maps-api-key",
threshold_g_kwh=150
)
def weekly_batch_training():
"""
This training run executes only when
the Italian electricity grid is sufficiently green.
"""
from codecarbon import track_emissions
@track_emissions(country_iso_code="ITA", project_name="weekly-batch")
def _train():
import time
print("Training started in green window...")
time.sleep(5) # Placeholder for real training
return {"accuracy": 0.94}
return _train()
Structured Logging and Production Monitoring
In production, emissions must be integrated with existing observability systems.
CodeCarbon supports output to standard Python loggers, which can be forwarded to
Datadog, CloudWatch, Prometheus, or any monitoring system.
# monitoring/carbon_exporter.py
"""
Exports emission metrics to Prometheus for production monitoring.
"""
import logging
import json
from codecarbon import EmissionsTracker
from typing import Any
# Configure structured logger for CodeCarbon
logging.basicConfig(
level=logging.INFO,
format='{"timestamp": "%(asctime)s", "level": "%(levelname)s", "message": %(message)s}'
)
logger = logging.getLogger("carbon.emissions")
class CarbonMetricsExporter:
"""
Wrapper around EmissionsTracker that exports metrics
in a format compatible with monitoring systems.
"""
def __init__(
self,
project_name: str,
service_name: str,
environment: str = "production"
):
self.project_name = project_name
self.service_name = service_name
self.environment = environment
self.tracker = None
def start(self):
self.tracker = EmissionsTracker(
project_name=self.project_name,
save_to_file=True,
log_level="ERROR" # Silence CodeCarbon, use our own logger
)
self.tracker.start()
logger.info(json.dumps({
"event": "carbon_tracking_started",
"service": self.service_name,
"environment": self.environment
}))
def stop(self) -> dict:
if self.tracker is None:
return {}
emissions_kg = self.tracker.stop()
metrics = {
"carbon_emissions_kg": emissions_kg,
"carbon_emissions_g": emissions_kg * 1000,
"service": self.service_name,
"project": self.project_name,
"environment": self.environment
}
# Structured log for monitoring systems
logger.info(json.dumps({
"event": "carbon_tracking_completed",
**metrics
}))
# Export to Prometheus (if available)
self._push_to_prometheus(metrics)
return metrics
def _push_to_prometheus(self, metrics: dict) -> None:
"""
Sends metrics to the Prometheus Pushgateway.
Requires: pip install prometheus-client
"""
try:
from prometheus_client import CollectorRegistry, Gauge, push_to_gateway
registry = CollectorRegistry()
g = Gauge(
"carbon_emissions_grams",
"CO2 equivalent emitted in grams",
["service", "environment"],
registry=registry
)
g.labels(
service=metrics["service"],
environment=metrics["environment"]
).set(metrics["carbon_emissions_g"])
push_to_gateway(
"localhost:9091", # Prometheus Pushgateway
job="carbon_tracker",
registry=registry
)
except ImportError:
pass # prometheus_client not installed
except Exception as e:
logger.warning(json.dumps({
"event": "prometheus_push_failed",
"error": str(e)
}))
# Usage
exporter = CarbonMetricsExporter(
project_name="invoice-processing",
service_name="finance-pipeline",
environment="production"
)
exporter.start()
try:
# Your workload here
import time
time.sleep(1)
result = {"processed": 1000}
finally:
carbon_metrics = exporter.stop()
print(f"Emissions: {carbon_metrics.get('carbon_emissions_g', 0):.4f} gCO2eq")
Reference Data: Carbon Intensity by Cloud Region (2025)
The following data is based on official sources (IEA, Electricity Maps, EEA) and
cloud provider declarations for 2024-2025. Actual values vary by season and time of day.
Carbon Intensity and PUE for Major Cloud Regions (2025)
Provider/Region
Country
Carbon Intensity (gCO₂eq/kWh)
Avg PUE
Renewable %
Green Rating
GCP europe-north1
Finland
~12
1.07
97-98%
Excellent
AWS eu-north-1
Sweden
~13
1.08
94-96%
Excellent
Azure swedencentral
Sweden
~13
1.08
94-96%
Excellent
AWS eu-west-3
France
~56
1.14
20-25% (nuclear 70%)
Good
GCP europe-west1
Belgium
~87
1.09
75-82%
Good
AWS us-west-2
Oregon, USA
~136
1.12
40-45%
Fair
AWS eu-west-1
Ireland
~316
1.13
30-35%
Adequate
AWS us-east-1
Virginia, USA
~386
1.15
8-12%
Poor
AWS ap-southeast-2
Australia
~610
1.18
8-15%
Very Poor
GCP us-central1
Iowa, USA
~497
1.11
45-50%
Poor
Insight: The Finland vs. Iowa Paradox
GCP europe-north1 (Finland) and GCP us-central1 (Iowa) have similar compute costs per hour,
yet their emissions differ by a factor of 41x. Iowa generates more than
45% of its electricity from renewables, yet emits far more because its remaining mix still
includes significant coal and gas generation. Finland, with nearly 98% clean energy
(Norwegian hydropower, wind, nuclear), is the clearly superior choice for carbon-aware
ML workloads.
Conclusions and Next Steps
Measuring the carbon footprint of code is no longer optional for teams that want to operate
responsibly in 2025-2026. With CodeCarbon, a single line of code is enough
to start measuring; with Cloud Carbon Footprint, you gain visibility over
your entire cloud infrastructure. Integrating these measurements into CI/CD transforms them
into concrete operational constraints, exactly like performance tests.
The data shows that the most impactful optimizations are, in priority order:
Cloud region selection: up to 42x difference, same cost
Model architecture: early stopping, pruning, distillation → -30-50%
Temporal shifting: running during green-energy hours → -20-40%
Green Software Engineering is not incompatible with performance: in most cases, code that is
more energy-efficient is also faster, less expensive, and more maintainable. Sustainability is
a software quality metric, not an external constraint.
Useful Resources
CodeCarbon: codecarbon.io — Python library for emission tracking