Correcting "897 Fake Followers": What My Own Follower Data Actually Shows
TL;DR Three central claims in my May 2026 post "Found 897 Fake Followers on DEV.to" do not hold up against my own follower data. I'm correcting them here, with the method, so anyone can check. Original claim What t
TL;DR
Three central claims in my May 2026 post "Found 897 Fake Followers on DEV.to" do not hold up against my own follower data. I'm correcting them here, with the method, so anyone can check.
| Original claim | What the data shows |
|---|---|
| 897 of my followers were fake | The count came from accounts with an empty bio, plus a "no posts" point my code gave every account by default |
All 1,409 audited accounts followed only me (Following=1) |
A fallback default in my code, not a measurement |
| A November 2025 cohort sat dormant for 187 days, then followed me in May | All 338 of those accounts followed me in November 2025, the week they were created |
| The May 2026 follower flood was coordinated | Not shown. Those followers look like ordinary new DEV accounts, about 21% of the accounts created in the same ID range that week |
What still stands: upvote.club offered DEV follows for sale. What I can't show is that my follower bursts came from it.
What the original post claimed
After I published an article about a GitHub follow botnet on May 19, 2026, my DEV follower count jumped from about 600 to over 3,000 in five days. I audited 1,409 followers and concluded:
- 897 of them (63.7%) were coordinated fake accounts, flagged by a heuristic score of 3 or more.
- Every audited account had
Following=1, so its only outbound follow was me. - A November 2025 cohort was created, sat dormant for 187 days, then was activated to follow me in May.
- The accounts were likely bought through upvote.club, a points-based engagement marketplace.
I framed the attribution as correlation, not proof. But the first three points were presented as measurements, and they weren't.
Method
Everything here comes from DEV's Forem API with my own API key, plus public profile lookups. Anyone can repeat it on their own account.
-
Full follower list.
GET /api/followers/users?per_page=1000&sort=-created_at, paged until empty. The response includes acreated_attimestamp for each follow, even though the docs don't list it. I got 9,638 current followers. -
Complete follow history.
GET /api/analytics/historical?article_id=β¦returns afollowscount per day. It turned out to be account-wide: every one of my 58 articles reports the same value for the same day (82 of 82 days). Summed, it gives 10,235 follows, exactly matchingtotal_followersfrom/api/analytics/follower_engagement. That includes accounts that later left. -
Account creation dates. DEV assigns user IDs in creation order. I calibrated IDs against
joined_atfrom 404 profiles; the estimate's median error was 0 days, with 90% within 1 day. - A real baseline. For each follower burst, I sampled DEV accounts created in the same ID range that do not follow me, and compared their profiles with my followers'.
-
Exact-ID match between my original audit CSV and today's follower list. The avatar URL path contains the account ID; it agreed with
user_idfor all 9,620 followers that had one.
A caution for anyone repeating this: DEV's daily analytics has gaps. On some days it reports views for posts not yet published, and follows that the follower list dates several days later, because several days of data get stamped on one date. Use the follower list's own timestamps for dating follows. Separately, DEV's analytics reports 10,235 total followers while the follower-list endpoint returns 9,638 records. I haven't established why the two differ, so I don't read the gap as people leaving, and the analytics can't support any claim of a single-day purge.
No usernames are published here. The code, the fix, the tests, the aggregate tables and the analysis scripts are public at github.com/GnomeMan4201/devto-follower-forensics, so you can check these numbers or run the same analysis on your own account.
Finding 1: the "dormant" cohort followed me in November 2025
The 338 accounts in my November 2025 cohort followed me between November 14 and 20, 2025, within days of being created. They did not wait 187 days.
- All 338 IDs in that cohort (user IDs 3,610,947 to 3,619,885) match my original audit exactly, and every one still follows me.
- Every one of those follows is timestamped November 2025. None started in May 2026.
- Equal-sized ID ranges on either side hold 0, 1, 0 and 0 of my followers, so the block is real and sharply bounded.
The ID block is real, but on its own it isn't evidence of a bot cohort. I published two posts on November 14 and 15, 2025, and these are accounts created that same week, the same posting-linked pattern as my later bursts (Finding 4). They're about 4% of the accounts in that ID range. The dormancy story doesn't hold.
Finding 2: Following=1 was a code default
The claim that all 1,409 accounts followed only me came from a fallback value in my audit script, not from DEV's data. This is the line:
following = profile.get("followed_users_count", 1)
The profile endpoint doesn't return that field, so every account got 1. Four columns ended up identical in every row:
| Column | Value in all 1,409 rows |
|---|---|
| Following | 1 |
| Followers | 0 |
| PostCount | 0 |
| AvatarDefault | False |
Following, Followers and PostCount were filled by defaults for fields the API never returned. AvatarDefault failed differently: DEV serves avatars through an image proxy, so my check for default_profile_image.png at the end of the URL could never match. Real data is never that uniform. DEV's public user endpoints currently return no follower, following or post counts at all, so Following=1 can't be checked today either.
Finding 3: where 897 came from
The 897 figure doesn't match the method my post described. It matches the saved scores at a lower threshold.
The audit CSV's own scores:
| Score | Accounts | Reasons |
|---|---|---|
| 1 | 510 | No posts |
| 2 | 877 | Empty bio; No posts |
| 3 | 22 | Suspicious username; Empty bio; No posts |
- "No posts" fired on every account, because post count defaulted to 0.
- Accounts scoring 2 or more: 877 + 22 = 899. My saved
flagged_usernames.txtalso holds exactly 899 names, including both accounts I said I had removed as false positives. Subtracting those two gives the published 897, but the saved files never did that. I can't reproduce the published classification from what I kept. - The post described a score of 3 or more. In the saved data that's only 22 accounts.
- The post's six-signal version can't produce 897 either. With the defaulted columns, three signals (following one account, zero followers, zero articles) fire for everyone, so all 1,409 would be flagged.
In practice, the flagged accounts were my followers with an empty bio. That isn't a bot signal: 65β80% of new DEV accounts that don't follow me, sampled from the same weeks, also have empty bios.
Finding 4: my burst followers look like ordinary new DEV users
When I compared my followers with accounts created in the same ID ranges that don't follow me, my followers were no more bot-like. On some measures they looked slightly more real.
| ID window | Fully blank profile: my followers | Fully blank profile: non-followers | Share of accounts in the ID range that follow me |
|---|---|---|---|
| INV-001 block, Nov 2025 | 52% | 65% | ~4% |
| May 20β26, 2026 | 49% | 57% | ~21% |
| Nov 2β4, 2026 | 55% | 60% | ~16% |
| Nov 10β13, 2026 | 51% | 60% | ~12% |
Non-follower samples are 40 accounts per window, so treat the profile percentages as rough. Hash-style usernames (ending in _ plus hex) showed up at similar rates in both groups (30β51%), so they look like a DEV username default, not a bot marker.
Other checks pointed the same way:
- Account age: 99% of burst followers followed me within 7 days of creating their account. I found no sign that they were stockpiled old accounts.
- Timing: follows on burst days arrived around the clock, on the same daily curve as quiet days. The typical gap was 167 s, against 209 s if arrivals were random.
- One cluster: on Nov 10, 2026, about 100 follows arrived in 12 minutes. All were brand-new accounts, with no duplicate bios or avatars and locations spread across five countries. A shuffle test shows the cluster is a short surge in arrival rate, not machine-gun spacing. Holding each hour's count fixed, a 26-follow run almost never happens (p β 0.002). Holding each minute's count fixed, it's ordinary (p β 0.22β0.26). Their user IDs span only about 870 IDs, so they were created close together, alongside other new DEV accounts.
A plausible explanation is DEV's own onboarding suggestions, which DEV has described as based on the tags new users pick and on authors' recent activity in those tags. I haven't confirmed that this is what happened on my account. What I can show is that my follows track my posting closely: dated by the follower list's own timestamps, 87% arrived within 3 days of a post, 13% within 4 to 7 days, and only 0.2% more than a week after. Shuffling my post dates within each month gives 49β59% instead of 87% (0 of 3,000 shuffles matched). Leaving out May and November 2026, it's still 76% against about 30% expected, and only 6% of those follows came in the days before a post. The posts before every big follow day were tagged security, python and opensource. My burst followers' own posts lean heavily on #ai, and many published their first post the day they followed me. In one exploratory test, an account that signed up 5 days after my last post wasn't shown mine. One test proves little either way.
What this means for my numbers: 10,235 accounts have followed me, but DEV counts only 55 as engaged followers. 86 people have commented on my posts, and only 22 of them follow me.
What still stands
The evidence that a follow-selling operation targeted DEV is separate from my follower data, and none of it is affected by this correction.
- upvote.club's archived catalog offered DEV follows at $0.90 each, and its browser extension contained DEV-specific task code. My original post said the queue showed 3 active DEV orders, but the queue snapshot I preserved was empty for DEV, so I'm withdrawing that detail.
- In May 2026 I reported related marketplace accounts to DEV, and as I wrote then, DEV suspended 3 accounts and 34 articles the same day.
- My analysis of the "Helper App" browser extension stands on its own.
What I'm changing
- The original post gets a correction notice at the top that links here. The claims above get struck through, not deleted.
- The audit code now records missing fields as missing instead of filling in defaults, with regression tests. The original and fixed versions are side by side in the evidence repo. The old CSV is kept unchanged, with a note on which columns are defaults.
- The sign-up explanation gets tested directly: a fresh account created with security-related interests, to see whether DEV suggests mine.
- DEV support has been asked how onboarding suggestions worked in May and November 2026, including whether suggested follows were pre-selected. I'll update this post with their answer.
The lessons I'm taking from this:
- A default value in
.get()is a fabricated measurement once it reaches a CSV. - A column with the same value in every row is a bug until proven otherwise.
- A bot signal means nothing without a baseline of normal accounts, drawn from the same time window.
- Timestamps beat stories. The follow dates were available the whole time.
If you see something I got wrong here too, tell me in the comments.
And if you run these tests on your own account, I'd really like to know what you find, whether it matches my results or not. Post your aggregate numbers in the comments, with no usernames. The more openly we compare notes, the better our odds of telling real bot activity apart from normal platform behavior on DEV.
Originally published by Dev.to Security. Aggregated on AIWithGhost for educational purposes β full credit and traffic to the original publisher.