Dev.to AI πŸ€– Ai πŸ‘ 0 πŸ“– 7 min read

The ChatGPT-User Bot Reads Your Site Less Now. Here's How to Check Your Logs

If you grep your access log for ChatGPT-User every few weeks, you may have noticed the line count going down. You're not imagining it. Across 714 small business websites, ChatGPT-User fetched pages 3,344 times a day from

The ChatGPT-User Bot Reads Your Site Less Now. Here's How to Check Your Logs

If you grep your access log for ChatGPT-User every few weeks, you may have noticed the line count going down. You're not imagining it. Across 714 small business websites, ChatGPT-User fetched pages 3,344 times a day from 19 October to 1 November 2026, down 62% from 8,716 a day from 20 July to 2 August 2026. Over the same weeks, visitors arriving from ChatGPT more than doubled.

We build LovedByAI, and our WordPress plugin logs every request a recognised bot makes to the sites it runs on. That's where these numbers come from. The full study, with the weekly chart and method, is our Lab field note on ChatGPT reading less. This post is the developer version: what the two numbers are, why you should never add them together, and a standard-library Python script that splits them in your own log and flags a step change. We ran it before publishing; the output below is real (on a synthetic log, explained further down).

What is the ChatGPT-User bot, and how is it different from a ChatGPT visit?

Two different things show up in your log when ChatGPT is involved, and they mean opposite things for your business.

  • A read. A request whose user agent contains ChatGPT-User/1.0; +https://openai.com/bot. That's OpenAI's server opening one of your pages while ChatGPT answers someone. No human is looking at your site.
  • A visit. A request from an ordinary browser that came from a ChatGPT answer. ChatGPT usually adds utm_source=chatgpt.com to the link it shows; sometimes you only get chatgpt.com as the referrer. That is a person on your site.

There's a third OpenAI agent worth keeping apart: OAI-SearchBot, the crawler that builds OpenAI's search index ahead of time. It isn't a live fetch and it isn't a person.

What happened to ChatGPT-User traffic in 2026?

It fell in three steps, and OpenAI announced none of them:

Chart: ChatGPT page reads per day fell from about 8,000 in late July to 1,732 in the week of 26 October 2026, in three drops (20 Aug, 17 Sep, 28 Oct), while visitors from ChatGPT rose from about 260 to 695 a day, same 587 small business websites

  • 20 August 2026, right after a short spike from 9 to 19 August.
  • 17 to 18 September 2026. Comparing 4 to 17 September with 19 September to 2 October, the typical site lost 39% of its reads (393 sites down, 85 up) while visits from ChatGPT rose 13%.
  • 28 October 2026. On the same 587 sites we follow every week, reads went from about 3,400 a day (19 to 26 October) to about 1,300 a day (28 October to 2 November). Week against week, the typical site fell 49%, with 154 sites down and 6 up. Visits held steady, 658 to 695 a day.

Late July against late October, the typical site lost 66% of its reads. ChatGPT still read most of the sites every week (450 to 497 of the 587 from July to mid October, 411 in the week of 26 October). It opens fewer pages on each one.

We also checked whether OpenAI's index crawler took over the reading. In total, OAI-SearchBot rose 41%, but at the typical site it fell 9% (148 sites down, 124 up), so we don't think it did. We don't know why ChatGPT reads less. The hub lists the outside evidence (Ahrefs on how rarely ChatGPT runs web searches, OpenAI's own description of answering from cached pages).

Why does counting reads and visits together hide the drop?

Because they move in opposite directions. If reads fall while visits rise, one combined "ChatGPT" number barely moves.

We learned this on our own data. Our tracker writes one ChatGPT-User line for every ChatGPT visitor, so the visit shows up next to the real fetches. Visits more than doubled over the window, so leaving those lines in hid about ten points of the drop. The study subtracts them first. We also confirmed the 28 October step was in the real fetches, not in that subtraction: the tracker's own lines were flat, about 1,040 a day.

If you use any plugin or dashboard that reports "ChatGPT traffic" as one figure, find out which of the two it's counting before you read anything into the trend.

How do I find ChatGPT-User reads and ChatGPT visits in my access log?

On most WordPress hosts you can download the raw access log from the control panel (cPanel calls it Raw Access). Nginx and Apache both write the combined format by default, which is what this script reads. It needs Python 3 and nothing else.

"""ChatGPT reads vs ChatGPT visits, per week, from an nginx/Apache combined log.

  python3 chatgpt_reads.py access.log [access.log.1 ...]

reads  = requests whose user agent is ChatGPT-User (OpenAI fetching a page
         while it answers someone). A bot, not a person.
visits = requests from a normal browser that came from ChatGPT: the URL has
         utm_source=chatgpt.com, or the referrer is chatgpt.com.
OAI-SearchBot (OpenAI's index crawler) is counted on its own line.
"lumped" is reads + visits, the single "ChatGPT" number some dashboards show,
printed only so you can see how much of a drop it hides.

"blocked" counts ChatGPT-User requests that got a 4xx or 5xx: if that column
climbs while reads fall, the drop is your firewall, not OpenAI.

A week is flagged when reads fall 40%+ against the average of the two weeks
before it. Standard library only.
"""
import re
import sys
from collections import defaultdict
from datetime import datetime, timedelta
from urllib.parse import urlsplit, parse_qs

LOG = re.compile(
    r'\S+ \S+ \S+ \[(?P<ts>[^\]]+)\] "(?:\S+) (?P<path>\S+)[^"]*" '
    r'(?P<status>\d{3}) \S+ "(?P<ref>[^"]*)" "(?P<ua>[^"]*)"'
)
BOTS = re.compile(r"bot|crawl|spider|slurp|fetch", re.I)
CHATGPT_HOSTS = {"chatgpt.com", "chat.openai.com"}


def kind(path, ref, ua):
    if "ChatGPT-User" in ua:
        return "read"
    if "OAI-SearchBot" in ua:
        return "searchbot"
    if BOTS.search(ua):
        return None
    if "chatgpt.com" in parse_qs(urlsplit(path).query).get("utm_source", []):
        return "visit"
    if urlsplit(ref).hostname in CHATGPT_HOSTS:
        return "visit"
    return None


weeks = defaultdict(lambda: defaultdict(int))
for name in sys.argv[1:]:
    with open(name, errors="replace") as f:
        for raw in f:
            m = LOG.match(raw)
            if not m:
                continue
            k = kind(m["path"], m["ref"], m["ua"])
            if not k:
                continue
            day = datetime.strptime(m["ts"].split()[0], "%d/%b/%Y:%H:%M:%S").date()
            monday = day - timedelta(days=day.weekday())
            weeks[monday][k] += 1
            if k == "read" and m["status"][0] in "45":
                weeks[monday]["blocked"] += 1

print(f"{'week of':<12}{'reads':>7}{'visits':>8}{'lumped':>8}{'searchbot':>11}{'blocked':>9}  note")
prev, prev_lumped = [], []
for wk in sorted(weeks):
    w = weeks[wk]
    lumped = w["read"] + w["visit"]
    note = ""
    if len(prev) >= 2:
        base = sum(prev[-2:]) / 2
        if base and w["read"] <= base * 0.6:
            lbase = sum(prev_lumped[-2:]) / 2
            note = (f"reads {100 * (w['read'] / base - 1):+.0f}% vs prior 2 weeks "
                    f"(lumped: {100 * (lumped / lbase - 1):+.0f}%)")
    print(f"{wk.isoformat():<12}{w['read']:>7}{w['visit']:>8}{lumped:>8}{w['searchbot']:>11}{w['blocked']:>9}  {note}")
    prev.append(w["read"])
    prev_lumped.append(lumped)

Run it on one file or several (rotated logs are fine, as long as they're unzipped):

python3 chatgpt_reads.py access.log access.log.1

Example output: what a step change looks like

We didn't want to publish a customer's log, so we generated an eight-week synthetic one (make_sample_log.py, seeded, in the same folder as the script) that mimics the shape we saw: reads drop on 28 October, visits keep climbing, OAI-SearchBot and Googlebot as noise. These are not study numbers. This is the script's real output on that file:

week of       reads  visits  lumped  searchbot  blocked  note
2026-09-07      121      27     148         33        0  
2026-09-14      118      33     151         30        0  
2026-09-21      126      35     161         30        0  
2026-09-28      123      40     163         31        0  
2026-10-05      123      48     171         34        0  
2026-10-12      121      54     175         32        0  
2026-10-19      119      56     175         32        0  
2026-10-26       72      61     133         35        0  reads -40% vs prior 2 weeks (lumped: -24%)

Three things to read off it:

  1. The flag. Reads fell 40% against the two weeks before. The rule is deliberately blunt: a week at or below 60% of the previous two-week average. On a small site with a dozen reads a week, raise the bar or compare months instead, or noise will trip it.
  2. The lumped column. The same week looks like a 24% dip if you add reads and visits together. That's the masking from the section above, in miniature.
  3. The blocked column. All zeros. If ChatGPT-User requests start getting 403s or 429s, your firewall or CDN is turning OpenAI away and the drop is yours, not theirs. Requests your CDN blocks before they reach the server won't appear in this log at all, so a clean blocked column on the server is necessary but not proof.

What should you do when ChatGPT-User drops in your logs?

Mostly, stop watching it as a health metric. A quieter ChatGPT-User line is not lost ground on its own. Judge ChatGPT by the visits column: that's people. On our sites, visits from ChatGPT rose 160% between the same late-July and late-October windows, and 72% at the typical site (part of that jump is a week in mid October when ChatGPT's links lost their tracking tag and visits looked lower than they were).

What it does change is where you can win. If ChatGPT opens fewer pages live while answering, more of the answer comes from what it already holds about your business. That makes what your pages say when the bot does come by matter more than how often it comes.

And if the blocked column isn't zero, fix that first.

Original study and full dataset: https://www.lovedby.ai/lab/chatgpt-reads-less

πŸ“° Read the original article on Dev.to AI

Originally published by Dev.to AI. Aggregated on AIWithGhost for educational purposes β€” full credit and traffic to the original publisher.