scryops
menu

Observability turned on its own publication. This page is the honest accounting: how the site is built, what it loads, and how the footprint badge in the footer arrives at its numbers. Awareness, not absolution.

scry@ops:~$ cat colophon.txt
generatorHugo · static HTML, no server runtime
deliveryprebuilt files served as-is
analyticsUmami · cookieless, no personal data · script self-hosted; page-view events go to Umami Cloud
newsletterSubstack · a plain link, nothing loads from Substack until you click
feedRSS · every article, guide, how-to and Q&A, with its excerpt
offlineservice worker · reads from cache when the network drops
fontsall self-hosted — Space Mono, Courier Prime, IBM Plex Mono, Atkinson Hyperlegible, Press Start 2P, Doto, Pixelify Sans (no CDN; Pixelify re-cut for label sizes: C, G, S, Z, 2, 3, 5, 6 and 9 get apertures wide enough to stay open, and B a square stem, so none reads as O, 8 or S)
diagramsMermaid · pre-rendered static SVG (0 JS, themes via CSS vars)
deps0 runtime dependencies · budget: none by default
carbonestimated per visit — see method

Annual footprint

The loop opened when we first instrumented the publication closes here: the site measuring itself, published openly. 2026 is the baseline year — each future year lands beside it so the trend is visible, not just asserted.

scry@ops:~$ footprint --year 2026
pages33 published
median page2.8 KB · HTML, gzipped
heaviest25.1 KB · HTML, gzipped
shared35.4 KB · CSS + JS, cached after the first visit
font set289.1 KB · all faces, cached; a page uses a subset — Lite / blocked = 0
trendbaseline · first year of record

Measured from the built site (public/), gzipped, by scripts/footprint-report.py — inspectable and reproducible: run it after a build and you get these numbers. One third-party call: the Umami page-view event, a small POST to gateway.umami.is on every page. Pressing the newsletter’s Subscribe button sends one more small event the same way, so we can see which pages lead to sign-ups. Everything else (HTML, CSS, JS, fonts, diagrams and the analytics script itself) comes from this site. Every page sits well within its per-template budget (article 100 KB, guide 200 KB, front page 120 KB), and the whole site is small enough to cache offline in full.

Subscribing to the newsletter happens on Substack (scryops.substack.com), not on this site, and is covered by Substack’s privacy policy. The site only links there, so no Substack code or request runs on these pages.

Method

The footprint badge in the footer measures this page’s real network transfer using the browser’s Performance API — the same resource and navigation timing entries you’d read off any instrumented service. It sums transferSize across every resource the page actually pulled, then converts bytes to an estimated carbon figure:

gCO₂e = transferred_GB × Σ(segment energy, kWh/GB) × 494 gCO₂e/kWh

  data centre   0.055 operational + 0.012 embodied
  network       0.059 operational + 0.013 embodied
  user device   0.080 operational + 0.081 embodied
                                    ────────────────
                             Σ =    0.300 kWh/GB
  (a green-hosting factor would offset the data-centre operational
   share; we keep it 0 — github.io isn't a verified green host)

This is the Sustainable Web Design v4 model — the same one the CO2.js library implements — inlined into the footprint script so the badge adds no runtime dependency (keeping the 0 runtime deps budget above honest). Energy is summed across three system segments — data centre, network, and user device — each with an operational and an embodied share, then multiplied by the global grid intensity, 494 gCO₂e/kWh (Ember). It’s an approximation, not a meter — treat it as an order-of-magnitude signal, the way you’d treat a sampled trace rather than a billing record.

What the number honestly leaves out

  • Repeat visits read lighter. transferSize reflects the network, so cached assets count as ~0 on a return visit. That’s correct — a returning reader really does pull fewer bytes — but it means the badge shows less than a cold first load.
  • Cross-origin assets report zero. Resources served without a Timing-Allow-Origin header return transferSize: 0. Fonts are now all self-hosted and counted, diagrams are pre-rendered SVG with no library to load, and the Umami script is self-hosted too, so the meter sees it. What’s still hidden is the page-view event Umami posts to its own server, which sends no such header. It’s a small request, but the badge can’t weigh it.
  • It’s modelled averages, not your request. The SWD model uses global-average energy intensities and grid carbon — not your actual device, network, or the grid where the page was served. It’s a rigorous industry estimate, not a per-request measurement.
  • hugo server reads high. The local dev server doesn’t gzip its responses; production hosting does. The badge measures real transferSize, so testing it against localhost compares raw, uncompressed bytes to a budget sized for compressed transfer — a page can show “over budget” in dev while sitting well under it once deployed. scripts/footprint-report.py measures gzip and matches production; trust that number over a localhost reading if the two disagree.

The point isn’t a precise gram count. It’s the habit: a publication about seeing your systems clearly should be able to see itself.