DEV Community

hc_xshh
hc_xshh

Posted on

Five numbers on my dashboard that were true and still wrong

Every morning at 07:10 a script collects numbers for a dashboard I keep for my own blog: is the site up, what did I publish, how many people came, what Google showed, which posts did anything. None of the numbers is wrong. Several of them were, in practice, useless — because they were true in a way that made me read the wrong story.

These are the five that lied to me this month, with the arithmetic and the fix for each.

1. "Views are down 83% this week"

What it said. One morning: 290 page views, 290 visitors. The next morning: 50 views, 50 visitors. A 83% collapse, the kind of chart that makes you check whether the site is down.

Why it was wrong. The 7-day window had slid by one day. Cloudflare Web Analytics aggregates by UTC day, and the first window (2026-10-14 to 2026-10-20) contained a single crawler sweep on 10-14: about 250 page views across 20+ paths, where every path showed exactly one view and one visitor. The next window (10-15 to 10-21) no longer contained it. Same site, same traffic, different window.

The tell: 250 views and 250 visitors. Real readers occasionally read two pages. A ratio of exactly 1.00 across hundreds of views is a process walking your sitemap.

The fix: print the window next to every number, not in a tooltip. A metric without its window is not a metric, it is a mood. This one is now a labelled field in the data file, so the chart cannot be read without it.

2. "One page per visit means nobody reads past the landing page"

What it said. Pages per visit: 1.0. A classic engagement death signal.

Why it was wrong. The denominator included the crawler. When 250 of 290 "visitors" are one automated client fetching one page each, the average is arithmetic on a population that mostly does not read.

The fix: split automation out before computing anything per-user. Cloudflare's RUM GraphQL exposes a userAgentBrowser dimension, so the collector now queries two buckets and reports "non-bot views" as its own metric, with the bot share shown next to it. This week: 70 views in 7 days, 60 of them non-bot, 14% automated.

The uncomfortable part: after the split, pages per visit is still 1.0. Now the number means what I thought it meant the first time — people arrive on one page and leave. A metric can be broken and then confirm bad news; those are different events and I only learned which one I had by fixing the measurement first.

3. "Upvote ratio 0.61 — so 39% of voters disliked it"

What it said. A post read once gave 17 points and a ratio of 0.61. Read again two minutes later: 18 points, ratio 0.62. On a smaller post a week earlier, the same check gave 5 points at ratio 1.0, then 4 points at 0.84–0.86.

Why it was wrong. At single-digit and low-double-digit scores, platforms fuzz the ratio so outsiders cannot reverse-engineer individual votes. The fuzzing means "ratio 1.0" is not "no downvotes"; it is "not enough votes for us to tell you". Re-reading gives different numbers because the fuzz is recomputed.

The fix: at low counts, report counts and stop. Score and comment count are integers and reproducible; a ratio at n=5 is noise with a decimal point. If a trend matters, require two reads pointing the same way before writing it down.

4. "Zero traffic on two days"

What it said. The daily series had no rows for 2026-10-17 and 2026-10-19. Two flat-zero days between normal days.

Why it was wrong. Nothing was collected those days because the analytics beacon was not live on the site yet — it was added later. A missing row and a zero row rendered identically, and zero rendered as "traffic died".

The fix: missing data gets its own state, not a zero. The collector now writes the expected dates, marks the ones with no data as missing, and the chart draws a gap instead of a line at zero. The alert text lists the missing dates by name, because "no data" is information and "0" is a claim.

5. "4 clicks. No — 6 clicks."

What it said. The same Search Console panel, same 28-day window, two numbers: the headline said 4 clicks and 612 impressions; adding up the per-page table gave 6 clicks and 563 impressions.

Why it was wrong. Neither is wrong. At low volume Search Console applies thresholds and rounding in different places, so the aggregate and the detail do not reconcile. This is not a bug I can fix, and it is not a reason to distrust everything — it is a reason to stop treating one of them as "the" number.

The fix: print both, labelled, and never do arithmetic across them. My dashboard now stores the headline figures and the summed figures as separate fields. If a decision depends on the difference between 4 and 6 clicks, the decision is not ready to be made.

The rule I ended up with

Every number on that dashboard now has to answer four questions before I am allowed to act on it:

  1. What window is it over, written next to the number?
  2. Who is in the denominator — people, sessions, or automated clients?
  3. Is a missing value being rendered as a zero?
  4. At this sample size, is the difference I am looking at even measurable?

The dashboard still has plenty of numbers that are small. That is fine. Small is a fact; a small number presented without its window, its population and its missing days is a story, and usually the wrong one.


Drafted with an AI assistant from my own measurements; every number and link here was checked against the source.


The dashboard itself is a static page rebuilt every morning from the raw sources. The longer write-ups and the measurements live at Field Notes — no ads, no tracking, one-click unsubscribe.


Read next, from the same notebook:

Top comments (2)

Collapse
 
omyvnss profile image
Om Yaduvanshi •

the crawler-sweep one got me. a 1.00 views-per-visitor ratio looks boring on a dashboard and is actually screaming. printing the window next to every number is the cheapest fix on the list, and probably the one most people will skip.

Collapse
 
hcxshh profile image
hc_xshh •

ha, fair. 250 views and 250 visitors across twenty-odd paths, one page each: that's a crawler walking the sitemap, not a quiet week.

the window label is the part I kept. it also stops a number from changing meaning overnight, which was the actual problem.

and after filtering the bots out, #2 is still 1.0. the boring ratio turned out to be the real number. not the one I wanted, but it's honest.