September 1, 2026·8 min read

The number on my homepage has to be true

A big stat on a landing page is a promise. The easy way to show one is to hardcode an impressive figure and forget it. The honest way is to fetch the real number at build time — and to fail loudly rather than ship a stale lie.

By Andrew Pyle

Every landing page wants a big number on it — a hero stat, the impressive figure that says this is real and it's working. The trouble is that a big number is a promise to the reader, and the easiest way to display one is also the easiest way to break that promise: hardcode an impressive value, ship it, and let it slowly drift from the truth while nobody's watching. Six months later the page confidently states a number that was true once and isn't.

I didn't want a single number on my site I couldn't stand behind at any moment. So the hero stats aren't typed into the template. They're fetched from a real source when the site is built, and the pipeline is deliberately built to fail loudly rather than ship a number it can't verify. An honest stat is worth the extra machinery; a stale one is a small lie that erodes everything around it.

01A lie with a timer

A hardcoded number is a lie with a timer on it

The problem with typing an impressive figure into a template is not that it's wrong when you write it — it's right, that's why you wrote it. The problem is that it's frozen while the thing it describes keeps moving. It becomes less accurate every day after it ships, silently, because nothing connects the displayed figure to the reality it's supposed to reflect. It's a lie with a timer on it: true now, false later, and no alarm goes off at the moment it crosses over.

That silent drift is the specific danger, because you don't notice your own homepage. You wrote the number once and moved on; you don't re-read your landing page skeptically every week checking whether its claims still hold. So a hardcoded stat can sit there being wrong for months, quietly undermining everything next to it, and the first you hear of it is when a careful reader points out that your headline figure is stale. The fix has to remove the human from the loop of keeping it current, because the human — me — is exactly the unreliable part.

A hardcoded stat is accurate the day you ship it and drifting every day after. The danger isn't that it's wrong — it's that nothing tells you when it becomes wrong.

02Fetch at build

Fetch it from the real thing at build time

The fix is to connect the displayed number to its actual source, so the two can't drift apart. My homepage stat is a developer-activity figure — merged pull requests across the repos I work in — and it comes from the system that actually counts them, not from my memory. When the site builds, a small script named fetch-dev-activity.mjs calls the real system that owns that number, a contributions-snapshot endpoint, and bakes the fresh value into a data file the page reads. The figure on the page is, by construction, the one the source reported at build time. Its staleness is bounded by how often the site rebuilds, not by how often I remember to edit a template.

Baking it in at build time, rather than fetching it live in the visitor's browser, is a deliberate choice. The number changes slowly enough that build-time freshness is plenty, and baking it in keeps the page fast and cacheable — the visitor gets static prerendered HTML with a true number, not a page that phones home on every load. It's the same pattern I use for other slow-moving truth: compute it fresh at build, serve it static, let the rebuild cadence keep it honest. A background timer also refreshes the number every few hours between builds, so even a site left unbuilt for a while shows a value that's hours old, not months.

03Fail loud

Fail loud, don't ship a guess

The subtle part is what happens when the fetch fails or the data looks stale. The tempting behavior is to fall back to some default so the build doesn't break — but a silent fallback is how you ship a wrong number anyway, just by a different path. So the pipeline is built to be loud about the failures that matter. The sharpest case is a source that answers cleanly but is out of date: if the snapshot comes back fine but its own timestamp is more than thirty days old, the script refuses and exits with an error rather than ship a stale number dressed up as verified. A stat that says 'verified' has to be verified against something current, or it doesn't ship.

This is the same instinct as everything else I build around honesty: the failure mode you design against is the confident falsehood, not the visible error. A build that fails because it couldn't confirm the number is annoying and safe. A build that succeeds by shipping an unverified number is smooth and dangerous. I'll take annoying-and-safe every time, because the whole value of the stat is that a reader can trust it, and one silently-wrong number spends trust I can't easily earn back.

04Two kinds of failure

Not every failure deserves the same answer

The thing that took me longest to get right is that 'fail loud' can't answer every failure, or the failures that don't matter start breaking builds and I learn to ignore the alarm. A stale source of truth and a rejected password are real problems — they mean the number I'd ship is wrong or unverifiable, so those exit loudly and page me. But a network blip, a brief 500 upstream, a timed-out request — those aren't evidence the number is wrong, only that the wire was busy for a moment. Treating a hiccup like a catastrophe is its own dishonesty: it cries wolf until the real wolf gets ignored.

So the script sorts failures into two piles by what they imply. An authentication rejection or a provably stale source means the number can't be trusted: the build fails loudly. A transient network error, a timeout, or a missing credential in a context that never had one means only that this fetch didn't land — so, after a few retries with backoff, the script keeps the last good number and exits successfully. The rule underneath is simple: break the build when the truth is in doubt, not when the network is.

05Monotonic floor

The number only ever goes up

Keeping a last-good value only works if 'good' is written somewhere the deploy can't clobber. So every successful fetch also writes the number to a small cache outside the repo checkout, in a directory that survives the hard reset the deploy does on release. When a fetch can't reach the source, the page falls back to that cached snapshot rather than a blank or a zero — a real recent number, not a guess. The undo for a bad fetch has the shape I want everywhere: a known-good copy set aside before it's needed, not reconstructed under pressure after something's already broken.

One more guard comes from a property of this number: a cumulative count of merged pull requests only ever grows. So if the source reports a value lower than the best one I've already shipped, that's almost certainly an upstream glitch, not a real correction — and the script holds the higher number rather than let the page appear to go backwards. A genuine downward correction still takes an explicit flag, and the held case is logged loudly so a real regression stays visible instead of being silently smoothed over. The default protects the reader from a number that flickers; the escape hatch protects the truth from a number that's stuck.

06Small but load-bearing

Small feature, load-bearing principle

This is, on its face, a tiny feature — a number on a page. But it encodes a principle I care about more than any single stat: the numbers I show should be true at the moment I show them, and the system should make being true the path of least resistance, not a thing I maintain by hand. Vigilance fails; I've watched myself let details drift the moment they left my sight. So the honesty lives in the machinery, not in my attention. There's even a separate watchdog whose only job is to check how old the served number has gotten, on its own schedule, so a stale figure gets caught even if the refresh timer has died.

I've had to rip out fabricated and stale numbers from my own sites before, and it stung precisely because one inflated figure quietly discredits the real ones around it. A reader who catches it reasonably assumes the rest are suspect too. So now the numbers are fetched, verified, and defended by a pipeline that would rather break than lie — but only breaks when the truth is actually in doubt. It's a small amount of engineering in service of a simple promise: if there's a number on my page, it's true right now — and if it can't be, the page holds the last true one or doesn't ship at all.