Audit my site
Technical SEOIntermediateChecked against Google docs · Oct 2026

Log file analysis for SEO: what Googlebot and AI crawlers really crawl

Your access log is the server's record of every request a bot actually made. Verify which hits are really Google, split them by section, status and URL type, and you can see exactly where crawling goes wrong.

Author: Eugene Serbin, Head of SEO at Semalt Updated: 30 October 2026 Reading time: 23 min Visuals: 4

In short

Your server's access log records every request that reached it, including every visit from Googlebot and AI crawlers, so it shows what bots really crawl rather than what a tool predicts. Before you trust a line that says “Googlebot”, verify it with a reverse and forward DNS lookup or Google's published IP ranges, because the user agent can be faked. Then split the verified hits by section, status code, URL type and date, and turn each pattern into a concrete fix: links, redirects, error pages or robots.txt rules.

Why log files matter for SEO

Every other crawl data source is a model or a summary. A site crawler such as OurSEO Tools, Screaming Frog or Sitebulb shows how a bot could move through your links. Search Console's Crawl Stats report shows Google's own totals and a sample of example URLs. The access log is different: it is the server's record of each request it actually answered, one line per request, with the exact URL, the status code it returned and the bot that asked.

That is why log file analysis answers questions nothing else can:

Log analysis matters most on large sites, sites with faceted navigation or many parameters, and sites after a migration. On a small site with a clean structure it is still a useful health check, but you will rarely find crawl budget problems there.

What Google officially says

“You can verify if a request to your server really is from Google.”

Google — Verify requests from Google crawlers and fetchers. Google adds: “This is useful if you're concerned that spammers or other troublemakers are accessing your site while claiming to be from Google.”

“Caution: The HTTP user agent string can be spoofed.”

Google — List of Google's common crawlers

“Google's crawlers identify themselves in three ways:”

Google — Overview of Google crawlers and fetchers. The three are the HTTP user-agent request header, the source IP address of the request, and the reverse DNS hostname of the source IP.

“If many of these URLs are duplicates, or you don't want them crawled for some other reason (removed, unimportant, and so on), this wastes a lot of Google crawling time on your site.”

Google — Optimize your crawl budget. Of this factor, which it calls perceived inventory, Google says: “This is the factor that you can positively control the most.”

“If the site slows down (latency increases or response times become longer), or responds with server errors (5xx HTTP status codes) or rate-limiting signals (such as HTTP 429), the limit goes down and Google crawls less.”

Google — Optimize your crawl budget

“Determine which Google crawler is overcrawling your site. Look at your website logs or use the Crawl Stats report.”

Google Search Console Help — Crawl Stats report

What a log line contains

Most Apache and nginx servers write the combined log format by default. Each request becomes one line with the same fields in the same order. Here is a line that claims to be Googlebot smartphone requesting a sorted category page:

Annotated · One access log line in combined format
203.0.113.42 - - [28/Oct/2026:06:14:07 +0000] "GET /shoes/running/?sort=price HTTP/1.1" 200 18342 "-" "Mozilla/5.0 (Linux; Android 6.0.1; Nexus 5X Build/MMB29P) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/W.X.Y.Z Mobile Safari/537.36 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)"
203.0.113.42

1 · Client IP. The only field you can use to verify the bot. Awk field $1.

- -

2–3 · Identity and authenticated user. Almost always empty.

[28/Oct/2026:06:14:07 +0000]

4 · Date, time and time zone of the request. Field $4.

"GET /shoes/running/?sort=price HTTP/1.1"

5 · Method, path with query string, protocol. The path is field $7.

200

6 · Status code the server returned. Field $9.

18342

7 · Response size in bytes. Unusually small 200 responses can point to empty or soft 404 pages.

"-"

8 · Referer. Bots usually send none.

"Mozilla/5.0 … Googlebot/2.1 …"

9 · User agent. A claim, not proof: anyone can send this string.

The IP here is from a documentation range, so in real life this “Googlebot” line would fail verification: exactly the kind of fake you need to filter out.

Fields worth adding

Two extra fields make the log far more useful for SEO: the host (to separate subdomains served by the same server, since Google's crawl budget is per hostname) and the response time. In nginx, define a format and use it in your access_log line; $request_time is in seconds with millisecond resolution:

log_format seo '$remote_addr - $remote_user [$time_local] "$request" '
               '$status $body_bytes_sent "$http_referer" "$http_user_agent" '
               '$host $request_time';
access_log /var/log/nginx/access.log seo;

In Apache, %D adds the time taken to serve the request in microseconds and %{Host}i adds the host:

LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %{Host}i %D" seo
CustomLog /var/log/apache2/access.log seo

Appending the new fields at the end keeps the standard field numbers ($1, $7, $9) unchanged, so existing scripts keep working and the last field ($NF) is the response time.

Getting your logs

Hosting and servers

Logs are rotated: older files get names such as access.log.1 and access.log.2.gz. Read compressed files with zcat or zgrep instead of unpacking them.

CDN and load balancer logs

If a CDN such as Cloudflare, Fastly, Amazon CloudFront or Akamai sits in front of your site, the origin server never sees requests answered from the CDN cache, and the IP in the origin log may be the CDN's, not the bot's. Two consequences:

The same applies to load balancers and reverse proxies: the last hop's log has the real client IP; the application servers behind it may not.

How much data you need

Many hosts keep logs for only a few days. One day of data shows you a snapshot; crawl frequency only becomes visible over weeks. Collect at least 30 days for a first analysis, longer for large sites, and set up an archive if your host deletes old files. Always save logs before and after a migration, so you can see how Googlebot moves from the old URLs to the new ones.

Privacy and GDPR

Access logs contain IP addresses, and under the GDPR IP addresses are personal data. Treat logs like any other personal data:

Verifying real Googlebot

Scrapers and bad bots often send a Googlebot user agent, hoping you will not block them. If you count their hits as Google's, your analysis is wrong; if you block “Googlebot” by user agent to stop them, you may block the real one. So verify before you analyse.

Google offers two methods. “Manually: For one-off lookups, use command line tools. This method is sufficient for most use cases.” And: “Automatically: For large scale lookups, use an automatic solution to match a crawler's IP address against the list of published Google IP addresses.”

Manual check: reverse, then forward DNS

  1. “Run a reverse DNS lookup on the accessing IP address from your logs, using the host command.”
  2. “Verify that the domain name is either googlebot.com, google.com, or googleusercontent.com.”
  3. “Run a forward DNS lookup on the domain name retrieved in step 1 using the host command on the retrieved domain name.”
  4. “Verify that it's the same as the original accessing IP address from your logs.”

This is Google's own example from its documentation:

$ host 66.249.66.1
1.66.249.66.in-addr.arpa domain name pointer crawl-66-249-66-1.googlebot.com.
$ host crawl-66-249-66-1.googlebot.com
crawl-66-249-66-1.googlebot.com has address 66.249.66.1

The forward step matters. Anyone who controls the reverse DNS of their own IP range can make it return a name ending in googlebot.com, but they cannot make Google's DNS point that name back to their IP.

Diagram · How to verify a Googlebot request
Googlebot verification flow Take the IP from the log, run a reverse DNS lookup, check that the hostname ends in googlebot.com, google.com or googleusercontent.com, run a forward DNS lookup on that hostname and check it returns the original IP. If both checks pass the request is from Google; if either fails it is not. For large volumes, match IPs against Google's published JSON IP range files instead. 1 · IP from the log2 · Reverse DNS 3 · Check the domain4 · Forward DNS 66.249.66.1 host 66.249.66.1 googlebot.com, google.comor googleusercontent.com? host on that hostname:same IP as in the log? noyesno Not Google spoofed user agent Verified Google keep in the analysis Google's example → crawl-66-249-66-1.googlebot.com host crawl-66-249-66-1.googlebot.com → has address 66.249.66.1 At scale: match the IP against Google's published ranges (CIDR) instead of DNS lookups common-crawlers.json · special-crawlers.json · user-triggered-fetchers.json user-triggered-fetchers-google.json · user-triggered-agents.json
A request counts as Google only if both checks pass: the hostname belongs to Google and that hostname resolves back to the same IP.

Automatic check: Google's IP range files

For millions of log lines, DNS lookups are slow. Instead, download Google's IP range files and check whether each IP falls inside one of the ranges. “Note that the IP addresses in the JSON files are represented in CIDR format”, so use a library that understands CIDR, such as Python's ipaddress module. The files change over time, so refresh them regularly rather than hard-coding ranges.

Three kinds of Google requesters

Google groups its crawlers and fetchers into three categories, each with its own hostnames and IP file:

CategoryExamplesReverse DNSIP filerobots.txt
Common crawlersGooglebot, Googlebot-Image, Google-InspectionToolcrawl-***-***-***-***.googlebot.com or geo-crawl-***-***-***-***.geo.googlebot.comcommon-crawlers.json“always respect robots.txt rules for automatic crawls”
Special-case crawlersAdsBotrate-limited-proxy-***-***-***-***.google.comspecial-crawlers.json“may or may not respect robots.txt rules”
User-triggered fetchersGoogle Site Verifier***-***-***-***.gae.googleusercontent.com or google-proxy-***-***-***-***.google.comuser-triggered-fetchers.json, user-triggered-fetchers-google.json, user-triggered-agents.json“ignore robots.txt rules”, because a user requested the fetch

Do not be surprised by many different IPs. Google's crawlers run from many datacenters, and Google says: “Therefore, your logs may show visits from several IP addresses.” Also, “Google egresses primarily from IP addresses in the United States.” Seeing US IPs crawling a site aimed at another country is normal.

Which bots you will see

Google crawlers

Google publishes the list of crawlers that, in its words, are “more likely to show up in log files and that we've received questions about.” The ones that matter most for SEO analysis:

CrawlerUser agent in the logWhat it means for your analysis
Googlebot SmartphoneMozilla/5.0 (Linux; Android 6.0.1; Nexus 5X Build/MMB29P) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/W.X.Y.Z Mobile Safari/537.36 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)The main crawler for Google Search on most sites. W.X.Y.Z stands for the current Chrome version.
Googlebot DesktopMozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; Googlebot/2.1; +http://www.google.com/bot.html) Chrome/W.X.Y.Z Safari/537.36Usually a smaller share than smartphone. Compare the two to spot device-specific errors.
Googlebot-ImageGooglebot-Image/1.0Image crawling for Google Images and image features in Search.
Google-InspectionToolMozilla/5.0 (compatible; Google-InspectionTool/1.0) or a mobile string containing Google-InspectionTool/1.0Search testing tools such as the Rich Results Test and URL Inspection. Its crawl preferences have “no effect on Google Search or other products”, so treat these hits as tests, not as Search crawling.
AdsBotAdsBot-Google (+http://www.google.com/adsbot.html), plus a mobile variant with AdsBot-Google-MobileGoogle Ads checks landing page quality. For AdsBot, “The global user agent (*) is ignored”, so a User-agent: * block does not stop it.

Two crawlers you will not find by name. Googlebot-News “doesn't have a separate HTTP request user agent string”; it crawls with the normal Googlebot strings. Google-Extended, the robots.txt token that controls use of your content for Google's Gemini models, also “doesn't have a separate HTTP request user agent string”. Blocking it in robots.txt does not change what you see in the log.

AI crawlers

AI companies run their own bots, and many sites now see them every day. The main tokens at the time of writing:

AI crawler names, purposes, IP ranges and robots.txt behaviour change often. Before you report on them or block them, check each provider's current documentation. Several providers publish IP ranges for their bots; where they do, verify by IP just as you do for Google.

In practice, AI crawlers often fetch the HTML of a page without its scripts and styles, and many do not run JavaScript. If your logs show AI bots fetching only HTML on a site that builds its content in the browser, they may be seeing little text. Separate training crawlers from search and user-triggered fetchers: blocking a training bot and blocking a search bot have very different effects on whether you appear in AI answers.

Key analyses

Work only with verified bot hits. Then look at the data from these angles.

Diagram · Log analysis workflow
Six steps of a log analysis Collect at least 30 days of origin and CDN logs; filter to bot user agents and drop human IPs; verify bots by DNS or IP lists; segment by section, status, bot and device; compare the crawled URLs with your site crawl and sitemap; fix links, redirects, errors and robots.txt; then repeat next month. STEP 1STEP 2STEP 3 STEP 4STEP 5STEP 6 CollectFilterVerify SegmentCompareFix 30+ days of logsorigin + CDN bot user agentsdrop human IPs reverse + forwardDNS or IP lists section, status,bot and device with site crawland sitemap links, redirects,5xx, robots.txt repeat after the fixes go live, then monthly
Verification comes before any counting, and the comparison with your crawl and sitemap is where most fixes are found.

Crawl share by section

Group Googlebot hits by the first folder of the path (/shoes/, /blog/, /search/) and compare each section's share of the crawl with its importance to your business. If your product categories get a small slice while internal search results or tag pages get a large one, Google is spending its time where you do not need it.

Status codes served to bots

Count the status codes returned to verified Googlebot. On a healthy site the large majority are 200 (and 304 if you support conditional requests). Watch for:

Crawl frequency and recency

For each important URL, find the date of the last verified Googlebot hit and how many hits it had in the period. Pages that change often and still go weeks without a visit need stronger internal links and accurate sitemap <lastmod> dates. Also chart hits per day: Google says “your Google crawl rate should be relatively stable over the time span of a week or two”, so a sudden drop or spike is worth explaining.

Important URLs never crawled

Take the URLs from your sitemap and your own crawl, and find the ones with no Googlebot hit in the whole period. These are often deep in pagination, linked only from JavaScript, or new pages with few internal links. They usually line up with “Discovered – currently not indexed” in Search Console.

Orphan URLs: crawled but not linked

The reverse set is just as useful: URLs Googlebot requests that are not in your crawl or your sitemap. They can be old URLs from before a redesign, orphan pages nobody links to anymore, parameter variations or URLs linked from other sites. Decide for each group: link it, redirect it, or return 404 or 410.

Wasted crawl on parameters and duplicates

Count Googlebot hits on URLs with a query string and group them by parameter name: ?sort=, ?color=, ?sessionid=, ?utm_source=. Many hits on many combinations of the same listing are the classic crawl trap. Fix it at the source: stop linking to the variations, keep tracking parameters out of internal links, and block crawling of unneeded combinations in robots.txt. A canonical tag helps Google consolidate duplicates for indexing, but it does not stop Google from requesting the URLs.

Redirects and chains

List the redirected URLs Googlebot keeps requesting and where they lead. Google advises: “Avoid long redirect chains, which have a negative effect on crawling.” Update internal links and sitemaps to point straight at the final URL, and make each old URL redirect to its destination in one hop.

Response time to bots

With response time in the log, find the slowest templates for Googlebot and the times of day they slow down. Slow responses reduce how much Google crawls. A template that is fast for cached visitors can still be slow for Googlebot if bots mostly request uncached pages.

Resources: JavaScript, CSS and images

Googlebot fetches the scripts, styles and images it needs to render pages. Check that these requests get 200 responses, not 403, 404 or robots.txt blocks. A blocked or failing script can mean Google renders a page without its content.

Pages that look like soft 404s

Logs cannot see page content, but the size field gives a hint. Many 200 responses of almost the same small size on different URLs (empty search results, “no products found” pages) are candidates for soft 404s. Google warns that “soft 404 pages will continue to be crawled, and waste your budget.” Confirm by opening a few and checking the Page indexing report.

AI crawler activity

Count hits per AI bot, which sections they fetch, and which status codes they get. Large volumes from one bot can cost you server resources; zero visits from a search-oriented AI bot may mean a firewall or robots.txt rule is blocking it. Verify the bot before you draw conclusions.

Cheat sheet · What to look for in logs
Pattern in verified bot hitsWhat it usually meansWhere to look next
Many hits on ?sort=, filter or session URLsCrawl trap: links generate endless URL variationsInternal links to parameters, robots.txt rules
Important pages with no hits in 30 daysWeak internal linking or discovery problemClick depth, sitemap, Page indexing report
Many hits on URLs not in crawl or sitemapOld URLs, orphan pages or external links to dead URLsRedirect map, 404/410 decisions
High share of 3xxLinks and sitemaps still use old URLsInternal links, sitemap, canonicals
5xx or 429 spikesServer overload, deploys or aggressive rate limitingServer monitoring, firewall rules, Crawl Stats host status
Many small 200 responses of the same sizePossible soft 404s or empty templatesPage indexing report, the pages themselves
Slow responses on one templateUncached or heavy pages slowing crawlingDatabase queries, caching, server resources
“Googlebot” hits that fail verificationScrapers using a fake user agentBlock by verified IP, never by user agent alone
Sudden drop in daily Googlebot hitsNew robots.txt rule, errors or slower serverrobots.txt history, error logs, Crawl Stats
Each pattern is a lead, not a verdict: confirm it on the live pages and in Search Console before you change anything.

Command-line recipes

You do not need a special tool for a first analysis. These commands work on a combined-format log on Linux or macOS (and in Git Bash or WSL on Windows). Field numbers assume the standard format shown above.

1. Save the lines that claim to be Googlebot, from current and compressed logs:

cat access.log access.log.1 > all.log
zcat access.log.*.gz >> all.log
grep 'Googlebot' all.log > gbot-claimed.log

2. List the unique IPs and verify them with reverse DNS:

awk '{print $1}' gbot-claimed.log | sort -u > gbot-ips.txt
while read ip; do host "$ip"; done < gbot-ips.txt

Keep only IPs whose hostname ends in googlebot.com or google.com and resolves back to the same IP, then filter the log to those IPs (for example with grep -Ff verified-ips.txt, which matches each IP as a fixed string anywhere in the line). For large logs, match against the JSON IP ranges with a short script instead.

3. Status codes served to Googlebot:

awk '{print $9}' gbot.log | sort | uniq -c | sort -rn

4. Crawl share by top-level section:

awk '{split($7, p, "/"); print "/" p[2]}' gbot.log | sort | uniq -c | sort -rn | head -20

5. Most-crawled parameter URLs:

awk '$7 ~ /\?/ {print $7}' gbot.log | sort | uniq -c | sort -rn | head -20

6. Unique URLs crawled versus total hits:

wc -l < gbot.log
awk '{print $7}' gbot.log | sort -u | wc -l

7. Googlebot hits per day:

awk '{print substr($4, 2, 11)}' gbot.log | sort | uniq -c

The dates sort as text, which is fine within one month; across months, sort the output by date in a spreadsheet.

8. Last Googlebot visit to one URL:

grep '"GET /shoes/running/ ' gbot.log | tail -n 1

9. Slowest responses, if response time is the last field:

awk '{print $NF, $9, $7}' gbot.log | sort -rn | head -20

10. Requests per AI crawler:

grep -oE 'GPTBot|OAI-SearchBot|ChatGPT-User|ClaudeBot|PerplexityBot' all.log | sort | uniq -c | sort -rn

Here gbot.log is the verified file from step 2. For the never-crawled and orphan analyses, export the unique crawled paths to a file, export the URL list from your site crawl and sitemap, and compare the two lists with comm or a spreadsheet. For logs in the millions of lines, a log analysis tool or a database is easier than shell commands, but the questions stay the same.

Logs vs the Crawl Stats report

Search Console's Crawl Stats report (Settings → Crawl stats) is Google's own view of its crawling. It is a good first check and a good cross-check for your logs. Google notes: “This report is aimed at advanced users. If you have a site with fewer than a thousand pages, you should not need to use this report or worry about this level of crawling detail.”

Server logsCrawl Stats report
CoverageEvery request that reached your server (or your CDN, if you use its logs)“The Crawl Stats report currently reports most crawl requests, but some requests might not be counted for various reasons.”
URL detailEvery URL, every hit“Example URLs are not comprehensive, but just a representative example.”
Which botsAll bots, including AI crawlers and fakesGoogle's crawlers only, grouped by Googlebot type
Failed requestsOnly requests that reached the serverAlso DNS, connection and robots.txt availability problems
BreakdownsWhatever you buildResponse, file type, purpose (Discovery or Refresh), Googlebot type, host status
EffortAccess, storage, verification, privacy workNone: open the report

Expect the numbers to differ. Google says: “Therefore you might see slight differences between your site's request logs and the numbers reported here.” Three common reasons:

One more difference helps you: the report's purpose breakdown separates “Discovery: The URL requested was never crawled by Google before.” from “Refresh: A recrawl of a known page.” Your logs cannot tell you that directly, but over a long enough period you can see which URLs are new to Googlebot.

Turning findings into fixes

FindingFix
Important pages rarely or never crawledLink them from strong pages and hubs, reduce click depth, keep them in the sitemap with accurate <lastmod>.
Heavy crawling of parameter and filter URLsStop linking to unneeded combinations, keep tracking parameters out of internal links, block unneeded patterns in robots.txt.
Old URLs still crawled and returning 200Redirect them to the closest equivalent, or return 404 or 410 if there is none.
Many hits on redirectsUpdate internal links, canonicals and sitemaps to the final URL; collapse chains to one hop.
5xx or 429 served to GooglebotFix the failing templates or capacity; review rate limits. Google warns: “Be sure not to return 503 or 429 for more than two or three days”.
Slow responses to botsCache pages, optimise heavy queries, add server resources. Support 304 (Not Modified) for unchanged pages.
Suspected soft 404sReturn a real 404 or 410 for empty or removed pages, or add real content.
Scripts or styles blocked or failingAllow them in robots.txt and fix the errors so Google can render the page.
Fake Googlebot trafficBlock or rate-limit by verified IP, never by the Googlebot user agent.
Unwanted AI crawler loadAdd rules for that bot's token in robots.txt, or rate-limit it at the server or CDN, after checking the provider's documentation.

Avoid one tempting shortcut: adding noindex does not save crawling. Google explains that it “will still request, but then drop the page when it sees a noindex meta tag or header in the HTTP response, wasting crawling time.” After the fixes go live, repeat the analysis on fresh logs to confirm Googlebot has changed its behaviour.

Compare your logs with a full crawl

OurSEO Tools crawls up to 1,000 pages and records the status code, canonical, indexability and load time of every URL, so you can match the URLs bots request with the URLs your site actually links to.

69-point checklistTechnical crawlContent analysis

Common mistakes

FAQ

Do small sites need log file analysis?

Rarely for crawl budget. Google says that with fewer than a thousand pages you should not need the Crawl Stats report's level of detail, and the same is true of logs. Logs are still useful for checking errors served to bots, fake Googlebot traffic and AI crawler activity.

How much log data do I need?

At least 30 days for a first analysis, longer for large sites or slow-changing sections. Make sure your host does not delete logs sooner, and archive them before any migration.

Is a reverse DNS lookup alone enough to verify Googlebot?

No. Anyone can set the reverse DNS of their own IP to a name that looks like Google's. The forward lookup proves the name really points back to that IP. Google's steps include both.

Can I see Google-Extended or Googlebot-News in my logs?

Not by name. Google says neither has a separate HTTP user agent string; their crawling is done with existing Google user agent strings.

Why does Crawl Stats show different numbers from my logs?

The report does not count every request, it includes failed attempts that never reached your server, and it can count crawls Google skipped while your robots.txt was unavailable. Your logs, in turn, may miss CDN-cached requests or other servers.

Should I block AI crawlers?

That is a business decision. Blocking a training crawler mainly affects whether your content is used for models; blocking a search or user-triggered bot can remove you from that product's answers. Use your logs to see who visits and what it costs, then check each provider's documentation for the right token.

Sources

Quotes checked against the official pages on 30 October 2026.