PageCarbon

Tracks per-page CO2 emissions. WireCache buffer, bot sampling, 90-day raw retention with permanent hourly aggregates.

A ProcessWire module that tracks per-page resource usage and estimates the CO2 emissions of every front-end request. Adds a Setup → PageCarbon page in the admin with live statistics, an hourly chart, a ranked page table, and real-world CO2 analogies.

PageCarbon

GitHub: mxmsmnv/PageCarbon

Author: Maxim Semenov
Website: smnv.org
Email: maxim@smnv.org

If this project helps your work, consider supporting future development: GitHub Sponsors or smnv.org/sponsor.

Features


  • Estimates CO2 emissions per request using the Sustainable Web Design Model v4
  • Rates each page A / B / C / D based on milligrams of CO2
  • Tracks response size, PHP execution time, and peak memory usage
  • WireCache buffer — metrics accumulate in memory; batch INSERT to DB once per hour (zero per-request DB writes)
  • Bot sampling — only 1-in-N bot requests are recorded; human requests always recorded in full
  • 90-day raw retention — raw rows are pruned automatically; historical data is preserved forever in a compact hourly aggregate table
  • Daily maintenance runs automatically: aggregates raw data into page_carbon_hourly, then prunes old raw rows
  • Hourly CO2 bar chart for the last 24 hours — bars coloured A/B/C/D by average CO2/request, so optimisation gains are immediately visible; tooltip shows avg mg/request and Grade; SVG fallback if Chart.js unavailable
  • All-time totals combine raw + aggregate tables seamlessly; CO2 total auto-scales to μg / mg / g / kg
  • Real-world analogies — all-time CO2 total translated into 12 everyday equivalents (car km, espressos, kettles, phone charges, Netflix hours, emails, trees, LED bulb hours, subway trips, songs streamed, flights, Google searches)
  • Top 50 pages table: CO2 avg, range, exec time, response size, hits, rating, last seen
  • Manual controls: Flush buffer, Run maintenance, Clear all data
  • Storage info panel: raw row count, table size, retention window, last maintenance timestamp
  • DOCX export — one-click formatted report via pure-PHP PageCarbonDocx (no Composer, no Node.js)
  • Frontend APIgetStats($page) and renderBadge($page) for use in templates
  • Full AdminThemeUikit integration — native uk-card, uk-grid, uk-table, uk-button throughout; respects --pw-main-color CSS variable including dark mode

Installation


  1. Copy the PageCarbon folder to /site/modules/
  2. In the ProcessWire admin: Modules → Refresh → Install
  3. Two tables are created automatically:
    • page_carbon — raw request rows
    • page_carbon_hourly — permanent hourly aggregates
  4. Go to Setup → PageCarbon, visit a few front-end pages, then press Flush buffer — data appears immediately

Module files


PageCarbon/
├── PageCarbon.module.php # Main module (extends Process)
├── PageCarbonConfig.php # Config inputfields
├── PageCarbonDocx.php # Zero-dependency DOCX report generator
├── CHANGELOG.md
└── README.md

CO2 formula


Based on Sustainable Web Design Model v4 (Wholegrain Digital, 2024):

energy_kWh = (response_bytes ×ばつ 0.00000000006) // 0.06 kWh/GB — network + server + device
 + (exec_ms ×ばつ 0.000000003) // CPU penalty ≈ 3 W server
 + (peak_mem_MB ×ばつ 0.0000004) // RAM penalty — DRAM idle
CO2_mg = energy_kWh ×ばつ carbon_intensity ×ばつ 1000

Default carbon intensity: 436 gCO2eq/kWh (world average). Adjust in module settings.

Page rating


RatingCO2 per requestNotes
A< 100 mgExcellent
B100–300 mgGood
C300–700 mgNeeds improvement
D≥ 700 mgHeavy

Reference: the average web page produces ~500 mg CO2 per view (Website Carbon Calculator, 2024).

Real-world analogies


The dashboard displays all-time CO2 totals translated into 12 everyday equivalents. Coefficients used:

AnalogyCoefficientSource
Driving by car120 g CO2/kmEU average petrol car
☕ Espressos brewed28 g CO2/cupLCA studies
Kettles boiled32 g CO2/litreUK grid avg
Phone charges8.2 g CO2/chargeIEA estimate
Netflix HD streaming36 g CO2/hourCarbon Trust 2023
Emails sent4 g CO2/emailMike Berners-Lee
Trees needed (1 year)21 000 g CO2/yearavg deciduous tree
LED bulb on0.012 g CO2/hour10W, world avg grid
Subway trips35 g CO2/tripIEA urban transit avg
Songs streamed0.028 g CO2/songSpotify sustainability report
Short-haul flights255 000 g CO2/flightICAO economy class
Google searches0.2 g CO2/searchGoogle Environmental Report

Settings


SettingDefaultDescription
EnabledtruePause collection without dropping tables
Grid carbon intensity436gCO2eq/kWh for your region. See electricitymaps.com
Raw data retention90 daysRaw rows older than this are deleted during maintenance
Bot sampling rate10Record 1 of every N bot requests (1 = record all)
Exclude templatessearch, sitemapTemplates whose pages are skipped

Storage strategy


TableContentSize estimateLifetime
page_carbonRaw request rows~9 MB / 1k req/day / 30 daysPruned after retention window
page_carbon_hourlyHourly averages per page~15 MB / year at 10k req/dayPermanent

Bot sampling (default 1/10) reduces raw table volume significantly on high-traffic or heavily crawled sites.

DOCX export


Click Export DOCX in the admin footer to download a formatted report. The report is generated entirely in PHP using PageCarbonDocx.php — a zero-dependency class that builds the .docx via ZipArchive (PHP built-in). No Composer, no Node.js required.

The report includes:

  • Title block with site URL, date, and carbon intensity
  • Last 24-hour summary table (requests, human/bot split, CO2, rating, exec time, response size)
  • All-time summary table (totals, collecting since, retention, intensity)
  • Top 50 pages by CO2 with range, time, size, and rating badge (new page)
  • Rating scale reference table
  • Header (site name + date, right-aligned) and footer (page X of Y)

Frontend API


Use in templates to display per-page CO2 data.

getStats(Page $page): ?array

Returns stats from the raw table for the given page (human requests only). Returns null if no data.

Keys: avg_co2_mg, min_co2_mg, max_co2_mg, avg_ms, avg_kb, hits, last_seen, rating (A/B/C/D), rating_color (#hex).

$pc = $modules->get('PageCarbon');
$stats = $pc->getStats($page);
if($stats) {
 echo $stats['avg_co2_mg'] . ' mg CO2 · Rating ' . $stats['rating'];
}

renderBadge(Page $page, string $style = 'full'): string

Returns a ready-made HTML badge. Returns '' if no data.

Styles: full (default), compact, minimal.

$pc = $modules->get('PageCarbon');
echo $pc->renderBadge($page); // full — card with all stats
echo $pc->renderBadge($page, 'compact'); // single-line pill
echo $pc->renderBadge($page, 'minimal'); // inline label only

Bot detection


The following User-Agent fragments are treated as bots:

bot, crawl, spider, slurp, facebookexternalhit, semrush, ahrefsbot, mj12bot, dotbot, yandex, bingpreview, ia_archiver, archive.org, bytespider, gptbot, anthropic, claudebot, google-extended, petalbot, dataforseobot, seznambot

Requirements


  • ProcessWire ≥ 3.0.227
  • PHP ≥ 8.1 with ZipArchive extension (enabled by default in most PHP builds)
  • MySQL / MariaDB

License


MIT

More modules by Maxim Semenov

  • Context

    Export ProcessWire site context for AI development (JSON + TOON formats)
  • Ichiban (SEO control center)

    Comprehensive SEO module: meta/OG/schema, audit, redirects, revisions, email reports.
  • WireWall

    Advanced traffic firewall with VPN/Proxy/Tor detection, rate limiting, and JS challenge
  • Dimensions

    Stores product dimensions (×ばつH) and weight with selectable units of measurement.
  • Ally (a11y)

    Self-hosted accessibility widget powered by Sienna (MIT). Adds font, contrast, language, and navigation tools to any page. No external CDN — the JS bundle is served from your own server.
  • Subscribe

    Newsletter subscription handler with lists, double opt-in, honeypot, rate limiting and unsubscribe link.
  • Squad

    AI integration for ProcessWire. Supports Anthropic, OpenAI, Google, xAI, and OpenRouter.
  • Plausible Analytics

    Plausible Analytics dashboard using Stats API v2 with page-edit widget, traffic trends chart, and geo/device tabs.
  • Robots.txt

    Manage robots.txt file through the admin UI with presets and visual editor.

All modules by Maxim Semenov

Install and use modules at your own risk. Always have a site and database backup before installing new modules.

AltStyle によって変換されたページ (->オリジナル) /