I run a digital PR agency, which means I have a database of publishers who sell placements: what they charge, what they accept, what language they publish in. It has been growing since 2015 and nobody had ever asked it a question. Last month I finally exported it, filtered it down to 16,625 sites across 53 languages, and started poking at it in pandas with Claude sitting next to me.
The first number I pulled was the one everybody in my industry quotes: what does a sponsored article cost in English? The answer came back $380.
That number is correct and it describes nobody.
The split
English sites in the set have a median of $380, which is lower than the non-English median of $660. That already seemed backwards. English is the most competitive publishing market on earth and it looked like the cheap one.
So I split by where each site's readers actually live rather than what language it publishes in.
uk_us = ["US", "UK", "CA", "AU", "IE", "NZ"]
eng = df[df.language == "en"]
core = eng[eng.top_country.isin(uk_us)]
other = eng[~eng.top_country.isin(uk_us)]
print(len(core), core.price.median()) # 3780 593.0
print(len(other), other.price.median()) # 1697 150.0
Two populations. A site whose readers are mostly in Australia has a median of $1,330. A site publishing in English for readers in India: $100. Both are "English guest posts." The $380 sits in the valley between two humps, and there is almost nothing actually priced there.
Every English price quoted in my industry, including by me, for years, has been the average of those two distributions. That's not a small error. If you budget from $380 you are simultaneously overpaying for one half of the market and unable to afford the other half.
Where devs have already met this
I'd love to claim this as a marketing insight but it isn't. It's the thing that happens to any team reporting a mean latency across two regions, or an average response time across cached and uncached paths. The aggregate is arithmetically fine and describes no request that ever happened. You've all seen the bimodal histogram where the p50 sits in the empty middle.
What was new to me was watching it happen to a number I had personally repeated to clients for a decade. I had the data to catch it the whole time. I just never plotted the distribution, because the summary statistic was always right there and always sounded reasonable.
The lesson I'd hand back to anyone doing this: describe() before mean(). If the histogram has two humps, the median is a coordinate, not a description.
The one that reversed my prior
The second finding I did not want.
A tenth of publishers in the set sell nofollow links only, meaning the link carries no ranking signal. My whole industry treats nofollow as the discount bin. Those publishers quote a median of $1,840, against $510 for everyone else. At the very top of the market, 39% of sites are nofollow-only.
The most expensive placements in the dataset pass no link equity at all.
I ran the groupby three times because I assumed I'd mixed up a filter. I hadn't. Large publishers don't sell ranking signals, they sell their audience, and they price that like advertising. The thing my industry has spent twenty years optimizing for is the thing the best sites decline to sell.
All of it, with the sample sizes and the method, is in the study I published at ESBO Ltd last week. Every number has an n next to it because the whole point was to publish something citable rather than something flattering.
The part that connects to AI
The reason a nofollow mention can be worth $1,840 is that the audience for a placement is no longer only human. Ahrefs tested 75,000 brands for visibility in AI Overviews and found branded web mentions correlated at 0.664 while backlinks came in at 0.218. Muck Rack, looking at more than 25 million links cited by ChatGPT, Claude and Gemini, found earned media accounts for 84% of AI citations and paid or advertorial content 0.3%.
An LLM reading a page does not check rel="nofollow". It reads the sentence. Twenty years of my industry's infrastructure is built around an attribute the newest and fastest-growing reader ignores completely.
The language split matters here for the same reason. Ask an assistant a question in Thai or Polish and it pulls from sources in that language, which is a point I made over at e27 recently. A brand can be well covered in English and absent the moment the question changes language. That is the same bimodal problem wearing different clothes: one aggregate number, two populations, and a decision made on the average.
What I actually changed
I stopped quoting a single price. Internally the number is now a pair, and any script that reports a median next to it also reports the interquartile range, because I no longer trust myself to remember which numbers are hiding a second hump.
If you have a metric you've quoted confidently for years without ever looking at its distribution, that's the one. Mine cost me about a decade.
This article was originally published by DEV Community and written by Boris Dzhingarov.
Read original article on DEV Community