All articles
SEO & GrowthSeptember 9, 2026 6 min read

Crawl Budget Forensics: Reading Your Log Files Before Googlebot Gives Up

Google Search Console tells you what got crawled. Log files tell you why the rest didn't. Here's how we run crawl budget forensics on programmatic sites before the traffic bleed starts.

Crawl Budget Forensics: Reading Your Log Files Before Googlebot Gives Up

Google Search Console will happily tell you that 340,000 of your 800,000 URLs are "Crawled — currently not indexed." What it won't tell you is that Googlebot spent 60% of its last week hitting your faceted filter combinations, your paginated tag archives, and a redirect chain from a migration you did in 2022. Log files will. This is the part of technical SEO most teams skip because it's annoying to set up — and it's usually where the real leverage is.

Why Log Files Beat GSC for Crawl Diagnostics

Google Search Console's Crawl Stats report is a sampled, aggregated summary. It's useful for trend lines, but it hides the URLs that matter most: the ones Googlebot is wasting requests on, and the ones it never reaches at all.

Raw server logs give you the ground truth:

  • Every request, with timestamp, status code, user agent, and response size
  • The exact URL patterns Googlebot prioritizes vs. ignores
  • Which sections of your site get re-crawled daily vs. once a quarter
  • Where redirect chains and soft 404s are silently eating budget

On programmatic sites with more than roughly 50k URLs, we treat log analysis as a monthly ritual. Below that, quarterly is usually fine unless you're actively scaling content.

What counts as "crawl budget" in 2026

Google has been consistent for years: crawl budget is a function of crawl capacity (what your server can handle) and crawl demand (what Google thinks is worth fetching). You can influence both, but you can only measure them honestly through logs.

Crawl capacity issues show up as elevated 5xx responses or slow response times correlated with Googlebot activity. Crawl demand issues show up as low re-crawl frequency on pages you care about, and high re-crawl frequency on pages you don't.

Getting the Logs Without Making Ops Hate You

The first blocker is almost always access. Depending on your stack:

  • Cloudflare / Fastly / CloudFront: enable log delivery to S3 or GCS. Cloudflare Logpush is the cleanest path if you're on Enterprise or the Logpush add-on.
  • Vercel / Netlify: use their log drains to a warehouse (Datadog, Axiom, S3). Default retention is short — you need to pipe them somewhere durable.
  • Nginx / Apache behind your own infra: rotate to S3 nightly with logrotate + a small uploader script.

What we need per request, at minimum:

timestamp | client_ip | method | url | status | bytes | referer | user_agent | response_time_ms

One warning: don't trust the User-Agent string alone. Fake Googlebots are common. Verify with reverse DNS lookups against googlebot.com and google.com, then forward-confirm. Google publishes the verification steps and an IP range JSON file — use it.

A minimal verification snippet

import socket

def is_real_googlebot(ip: str) -> bool:
    try:
        host = socket.gethostbyaddr(ip)[0]
        if not (host.endswith('.googlebot.com') or host.endswith('.google.com')):
            return False
        forward = socket.gethostbyname(host)
        return forward == ip
    except socket.herror:
        return False

Cache the results. Reverse DNS on millions of log lines will melt your pipeline otherwise.

The Four Questions Your Logs Should Answer

Once logs are landing in a warehouse (BigQuery, Snowflake, DuckDB — pick your poison), the analysis is mostly SQL. We consistently ask four questions.

1. Where is Googlebot spending its time?

Bucket requests by URL pattern. On a programmatic site, this usually means extracting the template segment: /city/[slug], /category/[slug]/page/[n], /search?q=, etc.

SELECT
  REGEXP_EXTRACT(url, r'^/([^/?]+)') AS section,
  COUNT(*) AS requests,
  COUNT(DISTINCT url) AS unique_urls,
  AVG(response_time_ms) AS avg_ms
FROM googlebot_logs
WHERE date BETWEEN '2026-01-01' AND '2026-01-31'
GROUP BY section
ORDER BY requests DESC;

If a section representing 3% of your indexable URLs is eating 40% of crawl requests, you have a leak. Common culprits: paginated archives, faceted search combinations, and calendar-style date archives.

2. What status codes is Googlebot actually seeing?

A healthy site sends Googlebot mostly 200s and 304s (Not Modified). Warning signs:

  • High 301/302 volume: redirect chains from old URL structures. Every hop is a wasted request.
  • High 404/410 volume: dead internal links or a sitemap referencing deleted content. 410 is honest; 404 is fine; soft 404s (200 with empty content) are the actual problem.
  • Any meaningful 5xx: capacity issue. Google will throttle you, and you'll feel it in re-crawl rates within days.

3. What's the re-crawl frequency for money pages?

Join your logs against your list of commercially important URLs. For each, calculate days since last Googlebot hit. If your top-converting templates have a median re-crawl gap of 30+ days, freshness signals aren't reaching Google fast enough. That's a crawl demand problem, and it usually traces back to weak internal linking or a bloated sitemap diluting priority.

4. What's Googlebot finding that you didn't intend to expose?

This is where the horror stories live. Search for patterns you don't recognize in the top-crawled URLs. We've found:

  • Staging subdomains indexed because someone forgot a robots.txt
  • Session-ID query parameters generating infinite unique URLs
  • JSON API endpoints returning HTML fallbacks (thanks, framework defaults)
  • Old A/B test variants still linked from footer templates

A War Story: The Filter Combinatorics Trap

We took over technical SEO for an e-commerce client with about 180k products and roughly 12M URLs indexed. Traffic had been flat for a year despite steady content investment. GSC showed "Discovered — currently not indexed" ballooning.

Log analysis revealed Googlebot was spending 71% of its requests on filter combination URLs like /shoes?color=red&size=10&brand=nike&sort=price_asc. The site generated a unique URL for every filter permutation, and internal navigation links exposed thousands of them. None were canonicalized properly; canonicals pointed to self.

The fix took two sprints:

  1. Consolidated canonicals to the base category URL for any combination beyond a single filter
  2. Added rel="nofollow" on filter links beyond the first level
  3. Blocked the deepest combinations in robots.txt (yes, we know Google says use canonicals — at this scale, robots.txt was the only way to actually stop the bleeding)
  4. Submitted a clean sitemap of the ~40k URLs that actually mattered

Within about six weeks, Googlebot's requests to the money templates roughly tripled, and organic sessions to those templates followed. No new content was created. We just stopped wasting the budget we already had.

Building a Repeatable Crawl Budget Dashboard

One-off analyses are useful; a persistent dashboard is what actually changes team behavior. We usually build something with these panels:

  • Daily Googlebot requests by status code
  • Daily requests by URL template/section
  • Re-crawl frequency distribution for priority URLs
  • Top 100 most-crawled URLs (with a flag for "should this be crawled?")
  • 404 and redirect volume trend
  • Average response time for Googlebot requests specifically

Stack we tend to reach for: Cloudflare Logpush → S3 → a scheduled job that loads into BigQuery or DuckDB → a lightweight Metabase or Grafana dashboard. Total infra cost for most mid-sized sites is under $50/month.

Alerting, not just dashboards

Set alerts on the metrics that break silently:

  • 5xx rate for Googlebot > 1% for 24 hours
  • New URL patterns appearing in the top 50 crawled with > 100 daily requests
  • Median response time for Googlebot > 2x the 30-day baseline

These three alone will catch most crawl-related incidents before they show up in GSC — which typically lags reality by 3 to 7 days.

Where We'd Start

If you've never looked at your logs before, don't try to build the full dashboard on week one. Do this instead:

  1. Get 30 days of logs into a warehouse. Even a laptop-local DuckDB file is fine to prove value.
  2. Verify Googlebot properly. Throw away the fakes.
  3. Run the section-level breakdown from question 1 above. Print it out, walk it to your team, and identify the biggest waste bucket.
  4. Fix that one thing. Measure the shift over the next four weeks.
  5. Only then invest in the dashboard and alerts.

Crawl budget work compounds. Every wasted request you eliminate is capacity Googlebot can spend on pages that make you money. If you want a hand running a first-pass audit on your own logs, our team does this work as part of our technical SEO engagements — but honestly, most engineering teams can do the first round themselves in a week.

#SEO#Technical SEO#Programmatic SEO#Log Analysis#Growth Engineering

Want a team like ours?

72Technologies builds production software for the kind of teams who actually read this blog.

Start a project