Skip to main content

AI Crawler Log Analysis: Your Server Log Is the Only Honest Signal

D

DL Minds Team

â€ĸ 17 min read
Share:
⚡ Quick Summary
  • Your access log is the only first-party record of an AI assistant touching your site. Analytics cannot see it, because a model reading a page is not a session.
  • Three things wear the label "AI crawler": training collection, search-index building, and live retrieval triggered by a user's question in the moment. Only the third correlates with citation.
  • User-agent strings are free text and trivially spoofed. Verify by reverse DNS or published IP ranges before you count anything.
  • Track which URLs get fetched, how often, what status you served, and whether your money pages are fetched at all.
  • Bot names and IP ranges change without notice. Read each operator's current documentation rather than any list in a blog post, including this one.

AI crawler log analysis is the practice of extracting AI-system requests from your raw server access logs — verifying them, aggregating them by bot and by URL, and reading the result as a measurement of how AI assistants actually see your site. It is the only genuinely first-party evidence available. Analytics will not show you a model reading a page: no pageview, no referrer, no cookie, no JavaScript. Only a line in your access log that your dashboard never looked at.

That fact reorganises the discipline. Everything else written about optimising for AI search — including what we have written — is advice that cannot be checked from inside an analytics tool. The log is what makes it falsifiable.

Why analytics cannot see AI assistants

Client-side analytics works by running JavaScript in a browser that then reports back. Every assumption in that sentence fails for an AI crawler. It fetches HTML over HTTP, often without executing JavaScript at all, keeps no cookie jar, and sends no referrer because there is no previous page. So a model can read your best article forty times in a month and your analytics will show zero, while your server quietly wrote forty lines about it.

Server logs are the complete record by construction: nothing reaches your application without passing through the web server first. Log analysis has always been ground truth for crawl-budget work in traditional SEO. It becomes the primary instrument, rather than an advanced technique, the moment your visibility depends on systems that never run your tracking script.

â„šī¸

This is the measurement layer. If you are building an AI-search programme, this post sits underneath AI search visibility tracking and measurement: that one covers what to measure across the whole funnel, this one covers the single data source you actually own outright.

Three kinds of AI crawler, and only one predicts citation

The biggest analytical error here is treating every AI-labelled request as one number. Three structurally different activities share the label, and most operators run separate agents for them precisely because the purposes are separate.

1. Training collection

A crawler gathering text that may be used to train or improve a model. Broad, slow-moving, and its effect on you is measured in model generations rather than weeks. A training fetch today does not put you in an answer tomorrow. This is also the category most licensing arguments are really about.

2. Search-index building

A crawler maintaining an index that an AI product queries when it needs current information. It behaves much like a conventional search crawler: systematic, recurring, coverage-oriented. Being indexed is necessary for retrieval, but it is not evidence of retrieval.

3. Live retrieval

A live retrieval fetch is a request your server receives because a specific person asked an assistant a specific question and the assistant decided your page might answer it. It is triggered by intent rather than by a schedule, and it is the one that correlates with being cited — because the fetch is literally part of composing an answer.

These look different in the log. They are bursty rather than even, cluster on specific URLs rather than sweeping the site, and often arrive in small groups seconds apart because the assistant pulled several candidate sources for one question. They also frequently hit pages a scheduled crawler visited weeks ago, which is the tell: the system already knew about the page and went back for it on demand.

Fetch typeTriggered byLog signatureWhat it tells you
Training collectionA collection scheduleBroad, even, low frequency per URLIn scope for corpus building. Little short-term signal.
Search-index buildingA crawl scheduleSystematic sweeps, sitemap-shaped coverageEligible to be retrieved. Necessary, not sufficient.
Live retrievalA user's question, right nowBursty, URL-specific, clustered in timeAn assistant considered your page for a real answer.

Operators document which of their agents does which job, and they change the arrangement. Treat that mapping as something you look up each quarter, not something you memorise.

How to find AI crawlers in nginx and Apache logs

First, make sure you are logging the user agent at all. The nginx combined format includes it; a custom format may not.

log_format ai_aware '$remote_addr - $remote_user [$time_local] '
                    '"$request" $status $body_bytes_sent '
                    '"$http_referer" "$http_user_agent" '
                    '$request_time';

access_log /var/log/nginx/access.log ai_aware;

Apache's combined LogFormat already carries %{User-Agent}i. Confirm it before you start — plenty of tuned configurations dropped the user agent years ago to save disk. Then pull the candidate lines:

# What AI-ish agents are hitting this box at all?
grep -Ei 'gptbot|oai-searchbot|chatgpt-user|perplexity|claudebot|
          anthropic|google-extended|bingbot|applebot|bytespider|ccbot' \
  /var/log/nginx/access.log | wc -l

# Which agent strings are present, and how often?
awk -F'"' '{print $6}' /var/log/nginx/access.log \
  | grep -Ei 'bot|crawler|spider|gpt|ai' \
  | sort | uniq -c | sort -rn | head -40

The second command is the more useful of the two, because it does not depend on you already knowing what to look for. Run it monthly: new agents appear, old ones get renamed, and the only way to notice is to look at what is actually in the file rather than at a list you wrote in March.

âš ī¸

Do not hard-code that grep list and walk away. Every name above is current at the time of writing and none of them is guaranteed to be current when you read this. OpenAI, Anthropic, Perplexity, Google, Microsoft and Apple each publish their crawler documentation, and that documentation is the authority — not a blog post, not a shared spreadsheet, not a third-party tool's built-in list.

Why you cannot trust the user-agent string

The user-agent header is arbitrary free text chosen by the client, so any script can claim to be any crawler. It is one line of code. People do it constantly — to bypass bot rules, to scrape behind a friendly-looking name, or simply because a default in some library was never changed.

This matters more than it sounds. If you count unverified user agents, your "AI crawler traffic" chart is partly a chart of people impersonating AI crawlers, and you will make content decisions on the basis of it. Verification is the difference between a measurement and a guess. There are two accepted methods, and the operator's documentation tells you which applies to their bot.

Reverse DNS, then forward-confirm

Take the requesting IP, resolve it to a hostname, check the hostname belongs to the operator's domain, then resolve that hostname back to an IP and confirm it matches the original. One direction alone is forgeable; the round trip is not.

ip=66.249.0.0                       # the IP from your log line
host=$(dig -x "$ip" +short)         # reverse lookup
echo "$host"                        # must end in the operator's domain
dig "$host" +short                  # forward lookup must return $ip

Published IP ranges

Several operators publish the IP ranges their fetchers use, often as a JSON file they update. You download the current file on a schedule and check the log IP against those CIDR blocks. Faster than DNS at volume, but only as accurate as your last refresh — so refresh it automatically, not by hand.

Either way, store the verdict alongside the log record and report two numbers: verified fetches and claimed-but-unverified fetches. The gap is itself interesting, and a spike in unverified requests claiming to be a well-known AI bot is usually a scraping problem worth a look.

A log pipeline you can stand up in an afternoon

You do not need a log platform for this. You need four steps, and they can be a cron job.

1
Extract

Filter the raw log to candidate bot lines and keep six fields: timestamp, client IP, method, path, status code, user agent. Drop query strings for aggregation but keep them in the raw copy.

2
Verify

For each distinct IP, run reverse DNS or a CIDR check against the operator's published ranges. Cache the verdict per IP for a day — the same crawler IP appears many times and re-resolving every line is wasteful.

3
Aggregate

Roll up two ways. By bot: fetches per day, status-code distribution, unique URLs. By URL: which bots fetched it, how many times, when it was last fetched. Both views are needed; either alone hides something.

4
Store and compare

Write the daily rollup to a table you keep. A single snapshot tells you almost nothing; the value is entirely in the trend after you publish, restructure a page, or change your markup.

On cadence: daily extraction, weekly review while you are actively changing things, monthly once it is steady. The one non-negotiable is that extraction runs before rotation deletes the file — losing a month of logs to logrotate is the most common way this project fails. A per-URL rollup needs nothing exotic:

# Top URLs fetched by verified AI agents, this log file
grep -Ei 'gptbot|perplexity|claudebot|oai-searchbot' access.log \
  | awk '{print $7}' \
  | sed 's/?.*//' \
  | sort | uniq -c | sort -rn | head -30

The metrics actually worth tracking

Raw hit counts are the least useful number available and the one every dashboard leads with. These four are worth the storage.

MetricWhat it answersWhat a bad reading looks like
Coverage of priority pagesAre the pages you care about fetched at all?Commercial pages absent while the archive gets crawled weekly.
Fetch frequency per URLHow current is the copy the model has?A page rewritten three months ago was last fetched before the rewrite.
Status codes served to botsWhat are you actually giving them?Anything but a wall of 200s and legitimate 304s.
Bot mix over timeWhich systems are paying attention?An operator that used to fetch regularly stops entirely.

The first row is the one people are least prepared for. Teams start expecting to learn how often they get crawled and instead discover their highest-value pages — the service page, the pricing page, the comparison page — have never been fetched at all, while a five-year-old blog post gets pulled constantly. That is a finding you can act on the same week, and analytics would never have shown it.

What a broken AI crawl looks like in the log

Four patterns account for most of what goes wrong, and all four are visible in a status-code-by-bot table.

  • Bots collecting 404s. Stale internal links, an old sitemap, or a URL structure that changed without redirects. You are spending someone else's crawl on nothing.
  • Bots served 403 or 429. Usually unintentional — a WAF rule or rate limiter deciding an unfamiliar agent is hostile. If you did not choose to block an AI crawler, being blocked by your own CDN is worth knowing.
  • Bots hammering low-value URLs. Faceted navigation, calendars, paginated tag archives, internal search pages. Classic crawl-budget waste wearing a new hat; the fix is the old one.
  • Priority pages never fetched. The quiet failure. Check internal linking, then whether the page renders without JavaScript, then your sitemap. A page nothing has fetched cannot be cited.

That last point connects directly to structure. If a page renders its substance only after a client-side fetch, a crawler that does not execute JavaScript sees an empty shell and your log shows a clean 200 that told the model nothing. A 200 is not evidence the content was received — it is evidence a response was sent.

💡

Pair the log finding with the structural fix. Once you know which pages get fetched, the question becomes what those pages give a model to work with — self-contained passages, clean markup, unambiguous entity naming. See how to get cited by ChatGPT and Perplexity and schema markup for AI search citations.

Should you block AI crawlers? Both arguments

Once the log tells you who is fetching what, the access-control question becomes concrete — and it is a business tradeoff, not a technical one. Both sides are held by serious people.

The case for allowingThe case for restricting
You cannot be cited by a system that cannot read you. Blocking retrieval agents removes you from answers you would have won.You are giving away content for free to a system that may answer the user without sending them to you.
Assistant referrals, where they exist, arrive with high intent — the person had context and clicked anyway.Where an assistant answers fully in-line, the visit never happens. That is a real cost for some publishing models.
Competitors who allow it occupy the space you vacate. The answer still gets composed; it cites someone else.If you sell access to the content itself — research, data, archives — free ingestion undercuts the product.
Crawler load is usually modest against normal traffic, so the infrastructure argument is weaker than it feels.Poorly behaved or unverified fetchers can generate real load, and blanket allowance hides abuse.

Two things sharpen the decision. First, it is not binary: because operators often run separate agents for training and for live retrieval, you can allow one and disallow the other, and many organisations land exactly there — comfortable being a cited source, uncomfortable being training data. Second, robots.txt is a request, not an access control. Well-behaved operators honour it; nothing enforces it. If you need enforcement, that is a server or WAF rule, not a text file.

Whatever you decide, decide it deliberately and write down why — in six months someone will ask why a page is missing from an assistant's answer and the cause may be a directive nobody remembers adding. The same caution applies to the various proposed AI-specific files doing the rounds; we looked at one in why llms.txt is not the thing to add.

Correlating fetch activity with assistant referrals

Fetch data tells you a system read your page. It does not tell you whether a human ever saw your name. To close that gap, line up two series against the same calendar. On the log side: verified retrieval fetches per week, segmented by the URLs you care about. On the analytics side: sessions whose referrer is an assistant domain — those do appear in analytics, because at that point a real browser is following a real link.

Then read the four combinations:

  • Fetches up, referrals up. The mechanism is working end to end. Do more of whatever produced those pages.
  • Fetches up, referrals flat. You are being read but not cited, or cited without a clickable link. Look at whether your page actually contains a liftable, attributable answer rather than a preamble.
  • Fetches flat, referrals up. You are being answered from stored knowledge rather than live retrieval. Brand and entity clarity are doing the work here.
  • Both flat. Coverage problem before anything else. Start at the crawl, not at the copy.

Be honest about the strength of this evidence: it is correlation over a shared timeline, not attribution. Assistants do not send a consistent referrer, users paste links rather than clicking them, and privacy settings strip referrers routinely. Treat it as a directional instrument — good enough to choose what to work on next, not good enough for a board deck without a caveat.

It also helps to have the identity work done, so a mention resolves to a searchable brand rather than a generic phrase (entity SEO and brand disambiguation), and to have answers structured so they survive extraction (FAQ schema and passage retrieval).

Common questions

Can Google Analytics show me AI crawler activity? No. Client-side analytics needs a browser to execute a tracking script and report back, and AI crawlers generally fetch HTML over HTTP without running JavaScript, without cookies and without a referrer. The fetch happens entirely below the layer analytics observes. Server access logs record every request regardless, which is why they are the only complete source for this.

How do I tell a real GPTBot request from a fake one? Never by the user-agent string alone — it is free text the client chooses and takes one line of code to forge. Verify the requesting IP instead, using either a reverse DNS lookup that you forward-confirm back to the same IP, or a check against the operator's published IP ranges. Each operator documents which method applies to their crawler.

How often should I analyse AI crawler logs? Extract daily, because log rotation deletes the raw files and you cannot recover what you did not capture. Review weekly while you are actively changing site structure or publishing into a new topic, and monthly once the pattern is stable. The value is in the trend across weeks, not in any single day's counts.

Does a crawler fetching my page mean I will be cited? No. A fetch means a system requested your page; a citation means it chose your page as a source for a specific answer. Live retrieval fetches — the bursty, URL-specific ones triggered by a user's question in the moment — correlate with citation far more closely than scheduled crawling does, but neither guarantees it.

Should I block AI crawlers in robots.txt? It depends on your business model, and it is a real tradeoff rather than a best practice. If discovery and citation are worth more to you than the content itself, allow them. If you sell access to the content, restricting makes sense. Because operators often run separate agents for training and for retrieval, you can also allow one and disallow the other.

Are the bot names and IP ranges in this article going to stay current? No, and you should not plan as if they will. Operators rename agents, split one crawler into several, and publish new IP ranges without announcement. Check each operator's own current crawler documentation before you rely on any identifier — and rerun a plain user-agent frequency count on your own logs periodically to catch agents nobody has written about yet.

✅ Bottom Line

Your access log is the only first-party evidence that AI systems interact with your site, and it is already being written whether you read it or not. Separate training collection from index building from live retrieval, because only the third correlates with citation. Verify every bot by reverse DNS or published IP range rather than trusting a header anyone can forge. Track coverage of your priority pages, fetch frequency, status codes and bot mix — not raw hits. Then line the trend up against assistant referrals and treat the result as a directional instrument. It is the step that turns AI-search work from opinion into something you can be wrong about.

â„šī¸
Verify identifiers at the source. Crawler names, user-agent strings and published IP ranges change without notice. Every operator maintains its own crawler documentation; that documentation is the authority, not this article.
Want this running against your own logs?
We build the extraction, verification and reporting into systems clients already run — so AI crawler coverage sits next to the rest of your performance data instead of in a one-off spreadsheet.
Talk to us →
D

DL Minds Team

Digital marketing and web development expert at DL Minds. Passionate about helping businesses grow through innovative technology solutions and strategic digital marketing.

Enjoyed this article?

Subscribe to our newsletter to get more insights and tips delivered straight to your inbox.