FIELD NOTE · 2026-08-03 · PORTFOLIO ENGINEERING · MEASUREMENT

Who Actually Reads This Portfolio

The analytics said 18,905 unique visitors. Somewhere between four and eight per cent of that was a browser with a person behind it. Here is how I measured the difference, and the estimate I got wrong before I measured it properly.

9 minRead time
4.3%Visitors that requested a favicon
98.6%Visits under 30 seconds
4,818Hits from one AI research tool
TL;DR — 60-second summary

Traffic went up 4.6× and got shallower at the same time. That combination is not growth, it is a different population.

In July 2026 this site logged 18,905 unique visitors against 4,088 the month before. Pages per visit fell from 2.05 to 1.33 over the same jump, and 98.6% of visits lasted under thirty seconds. Rather than argue about it, I used three things the site already ships — a favicon, a language pack and eleven ES modules — as instruments, because each of them is only requested by something that actually executes a page.

They agree with each other: real browser traffic was somewhere between 1,000 and 2,400 page views, against 28,033 reported. The rest was mostly undeclared automation, and the largest single identifiable source of it was an AI research tool. My first estimate, made with only one of the three instruments, was roughly twice too generous. That correction is why this note exists.

The number that started it

March through June had been flat and believable: about 4,000 unique visitors a month, 8,000 to 9,900 pages. July came in at 18,905 unique visitors, 20,970 visits, 28,033 pages. A 4.6× step change with no launch, no press and no campaign behind it.

The tell was not the size. It was that depth moved the wrong way. June ran 9,871 pages across 4,810 visits, or 2.05 pages per visit. July ran 28,033 across 20,970 — 1.33. Real interest and volume usually move together; when volume quadruples while depth falls by a third, the new arrivals are not doing what the old ones were doing.

Two days into August the same report showed 185 unique visitors, and the AI research tool that had generated 4,818 hits in July was completely absent. Whatever July was, it was an event, not a new baseline.

Three instruments the site already had

I did not want to argue from vibes about which visits were real, so I looked for things on the site that only a browser asks for. A process that fetches one HTML file and moves on does not request them; a browser rendering a page cannot avoid them.

1. The favicon

Every mainstream browser requests /favicon.ico when it renders a page. In July it was successfully served 826 times against 18,905 reported unique visitors — 4.3%.

2. The language pack

The internationalisation layer fetches /js/lang/en.json on load. It was requested 2,424 times, but appeared as the entry point for only 268 of them. The other ~2,150 were fetched from inside a session — meaning something had already parsed a page and run its script.

3. The module cluster — the strongest of the three

The site loads its behaviour as separate ES modules. In July their hit counts landed like this:

  • career-agent.js 1,146 · i18n.js 975 · blur-text.js 772
  • animations.js 658 · navigation.js 646 · border-glow.js 627 · command-palette.js 624 · evidence.js 624
  • app.js 621 · index-demo.js 621 · hero-canvas.js 603

Eleven files sitting between 603 and 658. That consistency is the evidence, not the numbers themselves. A crawler pulling HTML does not also pull eleven modules at near-identical counts; a browser rendering the page pulls all of them exactly once. The cluster is the shape of real rendering.

Read together — favicon 826, modules ~620, language pack ~2,150 in-session — the honest range is roughly 800 real sessions and somewhere between 1,000 and 2,400 real page views, against 28,033 reported. Four to eight per cent.

What the other ninety-something per cent was

The analytics package already separates traffic it recognises as robots: 10,534 pages and 20,335 hits in July, reported separately and excluded from everything above. So the question was what remained inside the “viewed” column — automation that does not announce itself as automation.

The user-agent table answered it. The third-largest user agent on the site was Google-NotebookLM, at 4,818 hits. Three Google proxy hosts accounted for 4,759 hits between them — close enough to the same population. Behind it: ClaudeBot 1,208, Go-http-client 1,051, AhrefsBot 1,075, ChatGPT-User 947.

Two individual hosts are worth naming as shapes rather than as culprits. One cloud address produced 1,003 hits across 777 separate visits — a hair over one request per visit, which is a scanner walking a list, not a person reading. Another produced 264 hits and zero successfully served files: pure probing.

The signature that made it unambiguous

The most-entered page on the site took 23.14% of all entries and 23.15% of all exits. Its viewed, entry and exit counts were 5,160, 5,126 and 5,058 — three numbers that are, for practical purposes, the same number.

A page whose exit count equals its entry count is not being browsed. It is being fetched. Pair that with 98.6% of visits finishing inside thirty seconds (average: 37 seconds) and there is nothing left to interpret.

The estimate I got wrong first

My first pass used only the language pack, and put real traffic at 7–9%. That was roughly twice too generous, and it was wrong for a boring reason: en.json is cached inside a session, so multi-page visits under-count, and I had no second instrument to catch the error.

The favicon count and the module cluster pulled the number down to 4–8% and agreed with each other independently. I am leaving the first estimate in this note rather than quietly replacing it, for the same reason the case studies keep a register of figures that could not be sourced: a number is only as good as the instrument behind it, and a single instrument has no way to tell you it is lying.

What this does not tell you

  • The favicon under-counts. Browsers cache it aggressively, so a returning reader may never request it twice. 4.3% is a floor, not a measurement of humanity.
  • So do the modules. Same caveat, same direction. Both instruments err towards saying there are fewer people than there are.
  • Robot detection is signature-based. Everything that identifies itself politely was already excluded. Anything that presents a plausible browser string and executes JavaScript would land inside my “real” band and I would not know.
  • One month, one site, shared-hosting logs. No sampling frame, no control, and the hosting layer geolocates cloud traffic to wherever the data centre is — which is why a datacentre-heavy month reads as an American one.
  • It cannot tell a hiring manager from a curious designer. Nothing here identifies intent. It only separates rendering from fetching.

The part that is not a complaint

It would be easy to write this as a story about being drowned in bots. That is not what the data says.

This site was deliberately built to be machine-readable: a maintained llms.txt and llms-full.txt, structured data on every page, component contracts published as JSON, a machine-readable profile, reciprocal hreflang. An AI research tool reading it 4,818 times in a month is that work functioning as designed. In the same period llms.txt was downloaded 36 times — exactly as often as my résumé.

And the channel is not purely mechanical. In both July and August, small numbers of visits arrived with chatgpt.com and perplexity.ai as their referrer: people who found this site because a model recommended it. Over the same month, Google referrals totalled 426 hits, or 0.59% of traffic, from four recorded search phrases — two of which were spam domains and two of which were somebody typing my own URL into a search box.

So the honest summary of my distribution is: almost nobody finds this site by searching for it. Machines read it thoroughly, humans arrive because a link was passed to them, and a few now arrive because a model passed the link instead of a person. That is a strange sentence to write about a portfolio in 2026, and pretending otherwise would not make it less true.

What I changed

Nothing about the pages. The finding is about measurement, so the change is to what I measure: I no longer look at unique visitors. The two numbers I track now are the favicon ratio and the module cluster, because those are the two that cannot be inflated by something that never rendered anything.

The wider conclusion was less comfortable and had nothing to do with analytics tooling. Against roughly 800 real sessions a month, the marginal value of the next case study is close to zero. The constraint on this portfolio is not how much is in it. It is that in July, referrals from other domains totalled 33 hits out of 71,810.

Method and sources

All figures are from the server-side analytics for edwson.com, July 2026 (full month) and 1–2 August 2026, read from AWStats and the raw log summary together. Nothing is sampled and nothing is modelled; every number above is a count that appears in one of those two reports. Percentages are computed from those counts and rounded to one decimal.

Predecessor note, on reading the same reports for funnel rather than population: Reading AWStats Like a Product Manager. The wider standard this note follows — every figure carrying its instrument, and figures that could not be sourced being listed rather than deleted — is set out in Data verification.

Portfolio thread

Where this connects

This note sits inside the Evidence & Verification Discipline thread — the same epistemic discipline applied to AWStats funnel data that I apply to A/B test pooled-SD calculations or regulatory citation audits in client work.

Thread

Evidence & Verification Discipline

How quantitative claims are sourced, validated, and presented — including the claims I make about my own portfolio

  • Portfolio funnel analysis — AWStats methodology Reading raw access logs for funnel diagnostics; expected lift hypothesis with measurement plan Field note · AWStats · funnel conversion · self-marketing rigor
  • Data Verification Methodology Sourcing, citation, and audit discipline for quantitative claims in financial UI Methodology · pooled-SD · Cohen's d · citation discipline
  • MiFID II Best-Execution Report Bps unit discipline for multi-instrument comparison Field note · measurement methodology · bps unit standard
  • Years Out · The Job Market You'll Graduate Into Public data tool · every panel labelled measured, estimated or proxy No client · 644,541 ACS records · states what it cannot tell you
  • Batch Authorisation · Threshold Tiering Publishes its own unsourceable figures No eng cost · 3 sourced · 4 demoted, not deleted