perf-sentinel v0.3.0
Major release focused on carbon scoring reliability, ecosystem coverage, and two new subcommands. This is the largest release since v0.2.0 and represents the Phase 5 work tracked in the roadmap (carbon reliability + ecosystem expansion). 10 commits between v0.2.3 and v0.3.0, 1012 tests passing (up from 476 at v0.2.3).
Highlights
- Carbon scoring precision ladder. Six energy backends now coexist with a clear precedence:
electricity_maps_api(real-time grid intensity via opt-in HTTPS API) >scaphandre_rapl(per-process RAPL on Linux bare metal) >cloud_specpower(CPU% + SPECpower interpolation for AWS / GCP / Azure VMs, ~180 instance types embedded from the Cloud Carbon Footprint coefficient tables) >io_proxy_v3(monthly x hourly profiles for 4 regions) >io_proxy_v2(hourly profiles for 30+ regions) >io_proxy_v1(flat annual, universal fallback). All six can be mixed in the same run; the top-levelco2.modeltag reflects the highest-precision source seen. - SCI v1.0 alignment (ISO/IEC 21031:2024). Carbon estimates now follow the Software Carbon Intensity specification from the Green Software Foundation, standardized as ISO/IEC 21031:2024. Total is
(E x I) + M [+ T]summed over analyzed traces, with embodied carbonM = traces * embodied_per_request_gco2and optional network transportTfor cross-region HTTP calls (default 0.04 kWh/GB, per Mytton, Lunden & Malmodin, J. Industrial Ecology 2024). EveryCarbonEstimatecarries a{ low, mid, high }confidence interval (2x multiplicative) and amethodologytag so downstream consumers can tell SCI-numerator values from per-R intensity values. - Multi-region scoring. OTel
cloud.regionattribute is read per span; scores are bucketed by region and returned asgreen_summary.regions[]sorted byco2_gco2descending. Per-service overrides are available via[green.service_regions]. 30+ cloud regions now have embedded hourly profiles sourced from ENTSO-E Transparency Platform and national TSOs (RTE eCO2mix for France, Fraunhofer ISE energy-charts.info for Germany, National Grid ESO Carbon Intensity API for the UK, EirGrid / TenneT / Svenska Kraftnat / Elia / Fingrid / Terna / REE / PSE / Statnett for the rest of Europe), EIA Open Data API for US balancing authorities (PJM, CAISO, BPA), Hydro-Quebec for Canada, and AEMO NEM / OpenNEM for Australia. - Per-operation energy coefficients. The proxy carbon model now weights energy per I/O operation by type: SQL
SELECT0.5x,INSERT/UPDATE1.5x,DELETE1.2x, HTTP payload size tiers (small <10 KB 0.8x, medium 10 KB-1 MB 1.2x, large >1 MB 2.0x). Coefficients sourced from Xu et al. (VLDB 2010) and Tsirogiannis et al. (SIGMOD 2010) foundational DBMS energy benchmarks, cross-validated against Siddik et al. DBJoules (2023) per-operation measurement study that confirmed 7-38% inter-operation variance. - Three new detectors.
chatty_service(too many HTTP outbound calls per trace),pool_saturation(sweep-line peak concurrency detection for connection pool contention), andserialized_calls(Weighted Interval Scheduling DP for parallelizable sibling spans). Seven detectors now run per trace, up from four. - Interpretation bands.
io_intensity_scoreandio_waste_ratioship with a stablehealthy/moderate/high/criticalclassification, rendered as colored parentheticals in the CLI and as*_bandfields in the JSON report. Thresholds are anchored on the detector constants (the N+1 detector'sCRITICAL_OCCURRENCE_THRESHOLDandConfig::default().n_plus_one_threshold) via drift-guard tests that fail at build time if either side moves without the other.
New subcommands
perf-sentinel tempo(feature:tempo, on by default). Query a Grafana Tempo HTTP API for post-hoc trace analysis, either by trace ID or by service + lookback window. Fetches OTLP protobuf, decodes viaprost, and runs the standard analysis pipeline. Supports--format text|json|sarifand--ciquality-gate mode. Dedicated 64 MiB body cap (MAX_TRACE_BODY_BYTES) for realistic traces with hundreds of spans.perf-sentinel calibrate. Tune the proxy model's energy-per-op coefficients from real RAPL / wattmeter measurements. Correlates a trace file with an energy CSV (power_wattsorenergy_kwh) by service and time window, writes a calibration TOML that the main config loads via[green] calibration_file. Model tag gains a+calsuffix when active (e.g.io_proxy_v2+cal). Energy CSV is capped at 64 MiB.
Breaking changes
CarbonEstimateandCarbonReportrestructured for SCI v1.0:CarbonContext.scaphandre_snapshotrenamed toenergy_snapshot(now aHashMap<String, EnergyEntry>carrying both the coefficient and the model tag).CarbonEstimategainssci_numerator_with_model/operational_ratio_with_modelconstructors; the pre-existingsci_numerator/operational_ratiostill work. No compat shim.[green] regionrenamed to[green] default_regionin.perf-sentinel.toml. Legacy flat name still loads with a deprecation warning.- New JSON fields on the report:
green_summary.io_waste_ratio_band,top_offenders[].io_intensity_band,green_impact.io_intensity_band, plus the structuredco2object withlow/mid/high/model/methodology, and thegreen_summary.regions[]per-region breakdown. Downstream consumers should ignore unknown fields. See the stability contract indocs/LIMITATIONS.md#score-interpretation.
Observability, performance, and hardening
- Cognitive complexity reduction. Nine functions flagged by SonarCloud's
rust:S3776rule were split into named helpers without behavioral change:compute_carbon_report(160 → below 15, extracted into 9 span/region/model helpers plus three supporting structs),load_custom_profiles,validate_cloud_services,extract_exe_label,detect_pool_saturation,longest_non_overlapping,validate_green,parse_energy_csv,parse_iso8601_utc_to_ms. 1012 tests still green, zero clippy warnings under-D warnings+clippy::pedantic. - Performance polish.
daemon::build_tick_ctxreturnsCow<CarbonContext>and borrows the base context when no scraper produced fresh data (no per-tick clone in the common case).daemon::apply_samplingkeys its decision cache on a u64 FNV-1a hash instead of aStringclone (zero heap allocations for cache keys on bursts).score::count_endpoint_statsmerges its double-probe HashMap pass into a single span loop via alast_seen_tracesentinel.score::cloud_energy::scraperparallelizes per-service Prometheus CPU% queries viatokio::task::JoinSet(1024 services at 20 ms used to serialize to ~20 s, now collapses to a single tail latency). - Three new Prometheus metrics:
perf_sentinel_service_io_ops_total{service}(per-service op counter feeding the scraper snapshot-diff path),perf_sentinel_scaphandre_last_scrape_age_seconds,perf_sentinel_cloud_energy_last_scrape_age_seconds. - Daemon shutdown hygiene. Ctrl-C now aborts all spawned tasks (gRPC, HTTP, JSON socket, Scaphandre scraper, cloud energy scraper, Electricity Maps scraper) before draining the window, so stray
tracing::error!lines do not leak after the "Shutting down" message. - Security. Calibrate energy CSV capped at 64 MiB to prevent local DoS. Three
unsafe { std::env::remove_var }blocks removed fromconfig.rstests via env-lookup dependency injection (sentinel-core is back to zerounsafeblocks). Predictable/tmptest paths replaced withtempfile::TempDir(symlink-TOCTOU safe, auto-cleanup on drop).daemon::run_json_socketgains a symlink pre-check so a local attacker cannot point the socket path at a victim file.ingest_from_tempoendpoint validator now rejects@only in the authority section (not in the path or query string) so?owner=foo%40example.comstyle URLs are accepted. - RUSTSEC-2026-0097 (rand unsound).
randbumped from 0.9.2 to 0.9.3 (which is in the patched range>=0.9.3, <0.10.0). A secondrand 0.8.5entry remains inCargo.lockas an optional subdep ofratatui-termwiz(a termwiz backend perf-sentinel never activates, we usecrossterm), documented as non-applicable inaudit.tomlat the repo root with the full exposure analysis. perf-sentinel cannot trigger the unsoundness regardless: we usetracing_subscriber::fmt()without a custom logger, so none of the five UB preconditions can be satisfied. - Test coverage. 476 tests at v0.2.3, 1012 at v0.3.0 (+536). The five network-facing scrapers (
daemon,tempo,cloud_energy,electricity_maps,scaphandre) gained mock-HTTP integration coverage in this release: happy path, 4xx / 5xx handling, malformed bodies, timeouts, body-cap enforcement, graceful abort on invalid URI.
Standards and data sources
perf-sentinel's carbon estimates now rest on an auditable chain of public standards, reference datasets, and peer-reviewed methodology:
Standard / specification
- Software Carbon Intensity v1.0 (ISO/IEC 21031:2024), Green Software Foundation.
co2.totalis the SCI v1.0 numerator(E x I) + M + T, not the per-R intensity.
Reference datasets
- Cloud Carbon Footprint (CCF): annual grid intensity per cloud region, per-provider PUE values, and SPECpower coefficient tables (~180 instance types) for the
cloud_specpowerenergy backend. - Electricity Maps: annual average intensities for 30+ regions (2023-2024) used as the
io_proxy_v1baseline, plus the real-time API (electricity_maps_apibackend). - ENTSO-E Transparency Platform: hourly generation and load data used to derive the monthly x hourly profiles for European bidding zones (FR, DE, GB, IE, NL, SE, BE, FI, IT, ES, PL, NO).
- National TSOs: RTE eCO2mix (France), Fraunhofer ISE energy-charts.info (Germany), National Grid ESO Carbon Intensity API (UK), EIA Open Data API (US PJM / CAISO / BPA), Hydro-Quebec annual reports (Canada), AEMO NEM / OpenNEM (Australia).
- Scaphandre: per-process Intel / AMD RAPL power measurement, scraped via its Prometheus endpoint when the
[green.scaphandre]section is configured.
Academic methodology
- Xu et al., Energy-Efficient Query Processing, VLDB 2010. Foundational DBMS per-operation energy benchmark.
- Tsirogiannis et al., Analyzing the Energy Efficiency of a Database Server, SIGMOD 2010. Companion benchmark establishing verb-level coefficients.
- Siddik et al., DBJoules: Towards Understanding the Energy Consumption of Database Management Systems, 2023. Confirms 7-38% inter-operation variance across verbs, cross-validation for the
per_operation_coefficientsfeature. - Guo et al., Energy-efficient Database Systems: A Systematic Survey, ACM Computing Surveys 2022. Overview of the field.
- IDEAS 2025 framework: real-time energy estimation model for SQL queries, referenced as the direction of travel for future
calibrateimprovements. - Mytton, Lunden & Malmodin, Estimating electricity usage of data transmission networks, Journal of Industrial Ecology 2024. Source for the 0.04 kWh/GB default on the optional
include_network_transportterm; the paper's 0.03-0.06 kWh/GB range is the origin of the configurablenetwork_energy_per_byte_kwhfield. - Boavizta API / HotCarbon 2024: bottom-up server lifecycle embodied carbon model, referenced for the
embodied_per_request_gco2default calibration.
These references are enumerated with inline citations in crates/sentinel-core/src/score/carbon.rs (top-level doc comment) and in crates/sentinel-core/src/score/carbon_profiles.rs (per-region source comments on every profile entry). The exhaustive per-region citation list is in docs/design/05-GREENOPS-AND-CARBON.md.
Install
# Prebuilt binaries (Linux amd64 / arm64, macOS arm64, Windows amd64)
curl -LO https://github.com/robintra/perf-sentinel/releases/download/v0.3.0/perf-sentinel-linux-amd64
chmod +x perf-sentinel-linux-amd64
sudo mv perf-sentinel-linux-amd64 /usr/local/bin/perf-sentinel# From crates.io
cargo install perf-sentinel# Docker
docker pull robintrassard/perf-sentinel:0.3.0Also available on GHCR: ghcr.io/robintra/perf-sentinel:0.3.0
Verify the binary against SHA256SUMS.txt:
curl -LO https://github.com/robintra/perf-sentinel/releases/download/v0.3.0/SHA256SUMS.txt
sha256sum -c SHA256SUMS.txt --ignore-missingFull changelog
Diff against the previous release: v0.2.3...v0.3.0. 10 commits, covering Phase 5a through Phase 5g plus the SonarCloud refactor and RUSTSEC patch.