Usage Estimation Methods
This section documents how the Ada Carbon Monitoring system estimates electricity usage and carbon footprint from CPU metrics.
Overview
The carbon calculation pipeline:
CPU Metrics (Prometheus)
│
▼
┌───────────────────────┐
│ Electricity │
│ Estimation │
│ (CPU → kWh) │
└───────────────────────┘
│
▼
┌───────────────────────┐
│ Carbon Intensity │
│ (UK Grid API) │
│ (gCO2/kWh) │
└───────────────────────┘
│
▼
┌───────────────────────┐
│ Carbon Footprint │
│ (kWh × Intensity) │
│ (gCO2eq) │
└───────────────────────┘
│
▼
┌───────────────────────┐
│ Attribution │
│ (User / Group) │
└───────────────────────┘
Key Concepts
Busy vs Idle
CPU time is categorized as:
- Busy: Active computation (user, system, nice, irq, softirq, steal)
- Idle: Waiting for work (idle, iowait)
Power Model
Different power consumption for each state:
- Busy power: 12W per CPU core
- Idle power: 1W per CPU core
Carbon Intensity
UK grid carbon intensity varies throughout the day:
- Low: 50-100 gCO2/kWh (high renewable generation)
- Moderate: 100-200 gCO2/kWh (mixed generation)
- High: 200-300+ gCO2/kWh (high fossil fuel generation)
Calculation Steps
Step 1: Get CPU Metrics
Query Prometheus for CPU seconds:
cpu_data = prometheus_client.get_cpu_usage_breakdown(
timestamp=datetime.now(),
cloud_project_name="IDAaaS",
host="172.16.100.50"
)
# Returns: {"busy": 1234.5, "idle": 56789.0}
Step 2: Estimate Electricity
Convert CPU seconds to kWh:
energy_kwh = electricity_estimator.estimate_total_kwh(
busy_seconds=cpu_data["busy"],
idle_seconds=cpu_data["idle"]
)
# Formula: (12W × busy + 1W × idle) / 3,600,000
Step 3: Get Carbon Intensity
Query UK Grid API:
intensity = carbon_client.get_current_intensity()
# Returns: {"intensity": 185, "index": "moderate"}
Step 4: Calculate Carbon
Multiply energy by intensity:
carbon_gco2eq = energy_kwh * intensity["intensity"]
Step 5: Attribute to User/Group
Match to workspace owner or facility:
user = mongo_client.get_user_by_platform_name(workspace["owner"])
# Or for groups:
group = f"{cloud_project}_{machine_name}"
Pages in This Section
| Page | Description |
|---|---|
| Electricity | Estimating kWh from CPU seconds |
| Carbon Footprint | Calculating gCO2eq from kWh |
| User Attribution | Attributing carbon to users |
| Group Attribution | Attributing carbon to groups |
Implementation
The calculations are implemented in ada-carbon-monitoring-api:
| Module | Purpose |
|---|---|
src/calculators/electricity_estimator.py | CPU → kWh conversion |
src/calculators/carbon_calculator.py | kWh → gCO2eq conversion |
src/calculators/carbon_equivalency.py | gCO2eq → equivalencies |
src/clients/prometheus_client.py | CPU metric queries |
src/clients/carbon_intensity_client.py | UK Grid API client |
src/models/workspace_tracker.py | Orchestration and attribution |
Example: Full Calculation
from datetime import datetime
from src.models.workspace_tracker import WorkspaceTracker
# Initialize tracker
tracker = WorkspaceTracker(
prometheus_url="https://prometheus.example.com",
mongo_uri="mongodb://localhost:27017"
)
# Track a group
entry = tracker.track_group(
cloud_project_name="IDAaaS",
machine_name="Muon",
timestamp=datetime.now()
)
print(f"CPU Time: {entry.busy_cpu_seconds_total + entry.idle_cpu_seconds_total:.1f} seconds")
print(f"Energy: {entry.total_usage_kwh:.4f} kWh")
print(f"Carbon: {entry.total_usage_gco2eq:.2f} gCO2eq")
print(f"Intensity: {entry.carbon_intensity_g_per_kwh:.0f} gCO2/kWh")
Output:
CPU Time: 287776.7 seconds
Energy: 0.0816 kWh
Carbon: 18.89 gCO2eq
Intensity: 232 gCO2/kWh