Log file analysis is the practice of reading your web server's access log to see exactly which URLs a search engine crawler requested, when it asked, and what your server sent back. Search Console reports what Google chose to tell you about your site. Your server logs record what Googlebot actually did, line by line, including the requests Google never mentions. This guide is for SaaS, developer-tools, and programmatic-content teams whose pages are being crawled inconsistently and who need evidence instead of a theory. It also covers the part no log-analyzer vendor will put on their own website: most sites are not big enough for this to be worth the effort yet.
The short version
- Most sites under roughly ten thousand URLs do not need log file analysis yet. That is GrowthHasten's recommendation rather than Google's position, and at that size Search Console answers the same questions for free.
- A server log is the only record of every request Googlebot made, including the ones Google's own reporting aggregates away.
- Verify the bot before you analyze anything. The user agent is a string the client sends, and a scraper can copy it in one line of code.
- The finding that pays for the exercise is almost always crawl waste: parameters, facets, pagination, and redirect chains consuming requests that should have reached your commercial pages.
- Logs tell you what was fetched. They tell you nothing about what was rendered, what got indexed, or how any of it ranked.
What is log file analysis in SEO?
It is reading the raw access log your web server writes every time something requests a file, then filtering it down to search engine crawlers. Every request leaves one line naming the IP address that asked, the timestamp, the request itself, the status code your server returned, the bytes sent, the referrer, and the user agent the client claimed.
Here is a single line in combined log format, which is what Apache and Nginx write by default. This is an illustrative example of the format, not data from any real site:
66.249.66.1 - - [12/Aug/2026:04:11:07 +0000] "GET /pricing HTTP/1.1" 200 41822 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)"
Read it left to right: 66.249.66.1 is the requesting IP, the bracketed value is the timestamp, GET /pricing is what was asked for, 200 is the status code that came back, 41822 is the response size in bytes, "-" is an empty referrer, and the long string at the end is the self-declared user agent.
Multiply that by a few million lines and you have a complete, timestamped account of how a crawler spent its requests on your site. What you do not have is anything that happened after the response left your server. Crawling, rendering, and indexing are three separate stages, and a log witnesses only the first one. That single limit shapes everything below.
What do server logs show that Search Console does not?
Per-URL detail, the full request history rather than a summary, and every other bot on the internet. Google's Crawl Stats report is free and genuinely useful, covering total requests, response codes, file types, crawl purpose, and which Googlebot type made each request. Where it stops is granularity.
Google says so directly. The Crawl Stats documentation describes its example URLs as a representative sample rather than a comprehensive list, and states the report is aimed at advanced users, adding that a site with fewer than a thousand pages should not need it. Your log has no sample. It has every line.
| What you want to know | Search Console Crawl Stats | Raw server logs |
|---|---|---|
| How many requests, and of what kind | Aggregated totals by response code, file type, purpose, and Googlebot type, plus example URLs | Every request your server received, with nothing summarized away |
| What happened to one specific URL | Only if it appears in the examples, which are explicitly not comprehensive | Every request to it, with timestamp, status code, and bytes |
| How far back you can look | A rolling 90 days | However long you retain the files, which you control |
| Whether it was really Googlebot | Pre-filtered by Google to its own verified crawlers | The raw user agent string, which you verify yourself |
| What every other crawler is doing | Not covered | Bingbot, AI crawlers, scrapers, uptime monitors, everything |
| The blind spot | Individual URLs, request sequence, and anything that is not a Google crawler | Rendering, indexing decisions, and rankings |
The two are not competitors. Crawl Stats is where you notice something is wrong. The log is where you prove what it is. If you have not exhausted the free reporting first, our guide to Search Console's reports covers the ones that answer this question without any of the work below.
Do you actually need this yet?
Probably not, and that is the most useful sentence in this article.
GrowthHasten's recommendation: below roughly ten thousand URLs, with no crawl symptom, skip log file analysis and go fix your internal linking instead. Ten thousand is our line, not Google's position, and we publish it as one number rather than a comfortable range because a range lets everybody talk themselves into the work.
Google's own documentation draws its lines higher and for a different purpose. The large-site crawl budget guide says it applies, as a rough classification rather than an exact threshold, to sites with more than a million unique pages changing weekly, or more than ten thousand unique pages changing daily, and tells everyone else not to bother reading it. Neither that document nor the Crawl Stats one is about log files, but both describe the same condition: crawling only becomes rationed when there is more to crawl than Google cares to fetch.
Work down this list and stop at the first honest yes.
- Can you name a crawl symptom? New pages taking weeks to appear, a large block of URLs sitting at
Discovered - currently not indexed, or an indexed count that stopped tracking your published count. A real symptom overrides every size rule below. - Are you above roughly ten thousand URLs? Count what your server can serve, not what your sitemap lists. Filter combinations, sort parameters, paginated series, and internal search results all count, and they are usually where the number actually comes from.
- Do pages generate themselves from a template or a database? Programmatic pages, directory listings, and large documentation sets create crawlable surface faster than any editorial team publishes. If your URL count grows while nobody writes anything, treat the size test as passed.
- None of the above? Stop here. Your crawl problem is almost certainly a linking problem, and the crawl paths your links create will explain more, faster, and for free.
In my experience the site-size question decides this before any tool question does. Teams arrive asking which log analyzer to buy, and at their size the honest answer is that the log would only confirm what Search Console already told them.
The threshold is a starting point, not a permission slip. A twelve thousand URL site with fast, complete indexation has nothing to find in its logs. A four thousand URL site where half the catalog has been invisible for two months has plenty.
Not Big Enough for Log Analysis Yet?
Run a free Website SEO Audit instead. It crawls your site and returns a prioritized list of technical SEO, crawlability, and indexability issues to fix first. No signup.
Run a Free SEO AuditHow do you get your log files?
From whichever machine actually answers the request, which is the part that catches most teams out.
- Your own origin server: Apache writes to
/var/log/apache2/access.logand Nginx to/var/log/nginx/access.log, usually rotated daily and compressed as.gz. The easiest case, because you own the machine and set the retention. - Managed and shared hosting: normally a raw access log download in the control panel, often limited to a short window. Ask what the retention period is before planning a quarter of work around it.
- Serverless platforms: on Vercel, Netlify, and similar hosts there is no server to log into. Logs are a streaming product, and useful retention is usually a paid tier or a drain to external storage. Configure it before you need it, because logs you did not collect cannot be recovered later.
- CDN edge: Cloudflare, Fastly, CloudFront and the rest offer log push or log pull, frequently on a business plan rather than the free one.
The CDN trap: edge logs and origin logs describe different populations of requests. Anything served from cache at the edge never reaches your origin, so an origin log on a well-cached site can miss most Googlebot activity and make your crawl look far smaller than it is. The edge log sees every request but says nothing about what your application did with it. When a CDN sits in front of your site, the edge log is the one you want, and you should confirm which one you were handed before drawing a single conclusion.
Two formats cover most of what you will be given. Combined log format: the space-separated line shown earlier, standard on Apache and Nginx. JSON lines: one JSON object per request, common on modern platforms and easier to parse programmatically. Either works, as long as the file preserves the user agent, the full request path including its query string, the status code, and the timestamp.
The request to send your platform team is short: seven to thirty days of raw access logs, taken at the edge if a CDN fronts the site, with query strings intact, user agent and status code preserved, and covering all traffic rather than a pre-filtered subset. Ask about the retention window in the same message, because that answer decides whether this becomes a repeatable check or a one-time favor.
How do you verify it is really Googlebot?
With a reverse DNS lookup followed by a forward confirmation, and it belongs at step one rather than in a footnote. The user agent field is text the client supplies. Anyone can put Googlebot/2.1 in it, and plenty of scrapers do, precisely because sites treat Googlebot generously.
Google documents two accepted methods in its guidance on verifying Googlebot:
- Reverse then forward DNS: run a reverse DNS lookup on the requesting IP with the
hostcommand, confirm the hostname sits undergooglebot.com,google.com, orgoogleusercontent.com, then run a forward lookup on that hostname and check it resolves back to the original IP. Both directions have to agree. A reverse lookup on its own is not proof. - IP range matching: Google publishes its crawler IP ranges as JSON files in CIDR notation, including
common-crawlers.jsonfor Googlebot andspecial-crawlers.jsonfor the rest. This is the method to automate, because it needs no DNS round trip per line.
Do this before you count anything. An unverified analysis measures a blend of Googlebot and whatever else was wearing its name, and every number downstream inherits the error silently.
The practical shortcut: verify the distinct IP addresses, not the individual lines. A week of crawling usually comes from a small set of addresses relative to the number of requests, so you verify a manageable list once and filter the whole file against it.
What are you looking for? The signal-to-fix ledger
A handful of patterns account for nearly everything a log analysis finds. Read the file against this ledger rather than browsing it, because a log rewards a specific question and punishes a general one.
| Signal in the log | What it usually means | What you change |
|---|---|---|
A cluster of 404 responses on URLs you still link to | Internal links or a sitemap pointing at pages that no longer exist | Fix the links at the source. Redirect only the URLs holding external links worth keeping |
5xx responses concentrated in a time window | Your server failed under crawl load, or during a deploy | Investigate capacity and deploy timing. Google slows its crawl rate when a site returns errors, so this compounds |
Long chains of 301 hops | Redirects accumulated across migrations, each added on top of the last | Flatten every chain to a single hop and update the internal links feeding it |
| Heavy crawling of parameter and facet URLs | Every filter combination is a distinct crawlable URL, and something is linking to them | Trace the links generating them, canonicalize or block the low-value combinations, and check what your directives permit |
| Requests to URLs with no internal links pointing at them | Orphan pages, usually left by an old sitemap, a stale export, or a deleted section | Decide deliberately: link them properly, or drop them from the sitemap and let them go |
| Googlebot never requesting your CSS or JavaScript bundles | Those files are blocked by a directive or served from a host the crawler cannot reach | Unblock what the renderer needs, then confirm the page Google builds matches the page you shipped |
| Crawl frequency skewed away from your commercial pages | Googlebot spends requests where your links and sitemaps point it, and that is not where your revenue is | Rebalance internal linking so the pages that matter are also the most linked pages |
| A Googlebot Smartphone to desktop split that surprises you | On a mobile-first indexed site, the smartphone crawler should account for the clear majority | If desktop leads instead, look for a separate mobile URL set or user-agent-dependent serving you had forgotten about |
Check the parameter and facet row first, for a structural reason rather than an anecdotal one. A template with five filters that each accept four values can generate hundreds of valid, distinct, crawlable URLs, every one returning 200 with near-identical content. Nothing about that is broken from the server's point of view, which is exactly why it survives a normal audit, and deciding which of those URLs are worth indexing and which to block is the next step once you've found them. The log is where it becomes visible, because there the requests are counted rather than theorized.
Read the whole ledger against what you have told crawlers they may fetch. A signal that looks like crawl waste is sometimes a directive doing precisely what it was written to do, and one that looks like a directive failing is usually a link you forgot you had.
Can you do this without a paid tool?
Yes, for the four questions that carry most of the value. A command line and a spreadsheet answer them, and answering them once tells you whether an analyzer is worth buying.
Filter the file to self-declared Googlebot first, then reduce it to your verified IP list:
grep "Googlebot" access.log > googlebot-raw.log
grep -F -f verified-ips.txt googlebot-raw.log > googlebot.log
From there, four checks. Field positions assume combined log format, where $7 is the request path and $9 is the status code.
- Which URLs get the most requests?
awk '{print $7}' googlebot.log | sort | uniq -c | sort -rn | head -50gives you the crawl priority Google has assigned your site. Compare that top fifty against your own list of important pages. The gap is the finding. - What is Googlebot getting back?
awk '{print $9}' googlebot.log | sort | uniq -c | sort -rngives the status code distribution. A healthy site is overwhelmingly200with a thin tail. Anything else is a shortlist. - What is being crawled that should not be?
awk '{print $7}' googlebot.log | grep "?" | sort | uniq -c | sort -rn | head -30isolates parameter URLs and ranks them by request count. This is the crawl waste check, and it usually takes under a minute. - What is not being crawled at all? Export the unique crawled URLs, paste them beside your sitemap URLs in a spreadsheet, and match the columns. Anything in the sitemap with zero requests has not been fetched, which is a different problem from being fetched and rejected.
Where a dedicated analyzer earns its price: when the file is too large for a spreadsheet to open, when you need the same analysis monthly without rebuilding it by hand, or when you want log data joined to your own crawl and to Search Console in one view. Screaming Frog's SEO Log File Analyser, Semrush, and Botify all sell into that category. Naming them is not an endorsement, and we have not tested them against each other.
What do logs not tell you?
More than most guides on this subject admit.
- Anything about rendering: the log records that a URL was fetched and how many bytes went out. It says nothing about what the crawler built from that response, whether your JavaScript executed, or whether the content you care about reached the rendered page.
- Anything about ranking: a heavily crawled URL is not a well-ranked URL. Crawl frequency reflects Google's interest in refreshing a page, not its position in results.
- Anything about indexing decisions: the log ends at the response. Whether Google indexed the page, picked a different canonical, or dropped it is Search Console's territory.
- Complete coverage, if the file was sampled: some managed hosts sample or truncate logs without announcing it. If your request counts look implausibly low, confirm you were given everything before interpreting the shape.
- Origin behavior, if you are reading edge logs: and the reverse holds too. Each layer is blind to the other, and mixing conclusions across them produces confident nonsense.
- Anything you failed to retain: logs are the one SEO dataset that cannot be backfilled. Once the window rotates away, the evidence is gone.
There is a privacy dimension too. Access logs contain IP addresses, which count as personal data under GDPR and comparable regimes. Involve whoever owns data handling before you export a month of logs to a laptop or upload them to a third-party tool.
How often should you run this, and what do you do with the result?
Quarterly for most sites that clear the threshold, monthly only for sites whose URL count changes on its own.
Monthly: large template-generated, programmatic, or catalog sites, where new crawlable URLs appear without anyone deciding to publish them. Quarterly: established sites above the threshold with a stable URL count and no active symptom. Once, two weeks after the event: any site of any size following a migration, a replatform, or a redirect map going live. That post-migration run is the highest-value log analysis most teams will ever do, because it catches redirect chains and orphaned sections while they are still cheap to fix. Never on a schedule: everyone below the threshold with nothing wrong.
A finding becomes work when it names three things: the URL pattern, the number of requests it consumed in your window, and the change that stops it. "Googlebot spent a fifth of last week's requests on ?sort= URLs" is a ticket an engineer can act on. "We have crawl waste" is a conversation that ends in another meeting. Write the pattern, the count from your own file, and the specific fix, and nobody has to rerun your analysis to believe you.
All of that is diagnosis. What you do with a rationed crawl once you can finally see it is a separate subject, and crawl budget optimization is where it goes next.
The habit worth building is smaller than the workflow: before blaming your content for an indexing problem, confirm the page was fetched at all. Most indexing arguments turn out to be crawling arguments nobody checked. This week, pull seven days of logs, filter them to verified Googlebot, and list the ten most requested URLs. If those ten are not the pages that make you money, you have your finding, and it sits inside the technical SEO layer the rest of your organic growth depends on. Running that check as a standing habit rather than a one-time audit is the kind of work our organic growth program is built around.
Ready to Grow Your Organic Traffic?
If crawl waste and inconsistent indexing are holding your pages back, GrowthHasten can help you turn the diagnosis into rankings, qualified traffic, and long-term organic growth.
Talk to an SEO ExpertFrequently Asked Questions
What is log file analysis in SEO?
It is reading your web server's access log to see every request search engine crawlers made to your site: which URL, when, what status code came back, and which user agent asked. Unlike a crawl simulation or a third-party estimate, it is a record of what actually happened, which makes it the only direct evidence of how a search engine spends its requests on your site.
What does log file analysis show that Search Console does not?
Per-URL detail, the full request history rather than a summary, non-Google bots, and requests Google's own reporting aggregates away. The Crawl Stats report gives you totals plus example URLs that Google describes as representative rather than comprehensive, and covers a rolling 90 days. Your log gives you every line, for as long as you retain it. The trade-off is that Search Console is free and instant, while logs need access, storage, and parsing.
How big does a site need to be before log analysis is worth it?
GrowthHasten's recommendation is roughly ten thousand URLs and up, or any size with a real crawl symptom such as new pages taking weeks to appear. That is our rule of thumb, not Google's position. Below that line, internal linking and Search Console's Pages report usually explain the problem faster and for free, so log analysis becomes a distraction rather than a diagnosis.
How do I verify that a request really came from Googlebot?
Run a reverse DNS lookup on the requesting IP, confirm it resolves to a googlebot.com, google.com, or googleusercontent.com hostname, then run a forward lookup on that hostname and check it returns the original IP. Google also publishes its crawler IP ranges as JSON files in CIDR notation, which is the method to automate. Skipping this step means you may be analyzing a scraper wearing Googlebot's user agent.
Can I do log file analysis without a paid tool?
Yes, for the questions that matter most. Filtering a log to verified Googlebot requests and then counting hits per URL and per status code answers the crawl waste question with standard command-line tools and a spreadsheet. A dedicated log analyzer earns its cost when the file is too large for a spreadsheet to open, or when you need to run the same analysis every month without rebuilding it by hand.
What can server logs not tell you?
Anything about rendering or ranking. A log records that a URL was fetched, not what the crawler built from it or where the page ended up in results. If your site sits behind a CDN, edge logs and origin logs also describe different populations of requests, so check which one you are reading before drawing a conclusion. Logs also cannot be backfilled once the retention window rotates away.
Tags

Anshuman Sinha
AI SEO Specialist, GrowthHasten
Anshuman Sinha is an AI SEO Specialist and Computer Science Engineer with over three years of experience in SEO and five years in web development. He specializes in Technical SEO, AI Search Optimization (AEO and GEO), SaaS SEO, and building high-performance websites with modern technologies.
View profile



