Technical SEO: A Crawl-First Audit
Crawl budget, indexing, canonicals, hreflang, and JS rendering — the foundation everything else builds on, audited to catch failures before they compound.

On this page
- Key takeaways
- The four pillars of technical SEO
- 1. Crawl budget: what it is and when to care
- How to run a log-file crawl audit
- 2. Indexability: the four states a URL can be in
- Soft 404s
- 3. Canonicals: the eight mistakes that silently destroy indexation
- Mistake 1: pointing every URL to the homepage
- Mistake 2: cross-domain canonical without ownership
- Mistake 3: paginated series without self-referential canonicals
- Mistake 4: trailing slash inconsistency
- Mistake 5: HTTPS vs HTTP mixed signals
- Mistake 6: canonical pointing to a 404
- Mistake 7: relative canonical URLs
- Mistake 8: canonical in the body
- 4. Redirects: chains cost more than you think
- The most common chain I find in audits
- The one-hop rule
- Redirect loops
- 5. hreflang: the three rules that most sites break
- The return-tag rule
- Self-reference
- x-default
- The ISO format rule
- 6. JavaScript rendering: Google’s two-wave system
- How to audit JavaScript rendering
- Hydration traps
- 7. Schema and structured data
- Validate before launch
- Monitor Search Console after launch
- Schema that errors is worse than no schema
- 8. Sitemaps: one per content type
- The right sitemap structure
- lastmod accuracy
- 9. Logs over crawl tools
- Frequently asked questions
- Does a 301 redirect pass all ranking signals?
- My canonical is correct but Google indexed the wrong URL. Why?
- How often does Googlebot re-crawl my pages?
- Should I submit a new sitemap every time I publish?
- My site uses a CDN. Do I still need technical SEO?
- Wrap-up
A page that Google cannot find is a page that does not exist. A page it cannot render is invisible. A page it can render but does not trust is buried. Technical SEO is the discipline that gets your pages found, read, and considered — before a single content word is written. This guide walks the audit the way senior consultants charge for it: crawl-first, evidence-based, with the rationale for every decision so you know what you are fixing and why.
Key takeaways
- Crawl budget management only matters above 10,000 URLs — below that, Google crawls everything.
- The canonical tag is the most powerful and most misused tag in SEO — eight common mistakes destroy indexation silently.
- Googlebot’s two-wave rendering system means JavaScript-dependent content can take days to appear in the index.
- Server logs reveal crawl behaviour that no crawl tool can simulate — bot frequency, response times, and render failures are all in there.
- Schema errors in Search Console are worse than no schema — validation before launch and monitoring after are non-negotiable.
- Redirect chains compound crawl waste — every hop costs budget and creates ranking risk.
The four pillars of technical SEO
Every technical SEO problem belongs to one of four buckets:
1. Crawl. Can Googlebot reach the page? Blocked by robots.txt, firewall, or authentication? A page that returns 200 but was never crawled is a crawl gap, not an indexing problem.
2. Render. Can Googlebot see the content? Server-side rendered HTML works immediately. JavaScript-rendered content waits for the second wave. If the critical content lives behind a JavaScript bundle that fails or defers, Googlebot sees nothing.
3. Index. Does Googlebot want to index it? The page signals intent through canonical tags, noindex directives, and internal link equity. A page can be reachable and readable but still excluded if the signals contradict each other.
4. Rank. Does Googlebot trust it? HTTPS, link equity from real referring domains, clean redirect chains, and absence of manual penalties all feed trust signals. A technical problem here — a redirect loop, a canonical to a 404, a mixed-content warning — can collapse trust overnight.
1. Crawl budget: what it is and when to care
Crawl budget is the number of URLs Googlebot will crawl on your site per day. It is determined by two factors: crawl rate limit (how fast Googlebot can crawl without harming your server) and crawl demand (how much Googlebot wants to crawl based on your site’s reputation and update frequency).
For sites under 10,000 URLs, crawl budget is effectively irrelevant — Googlebot will crawl everything and re-crawl regularly. The moment you cross 10,000 indexable URLs, you need to actively manage it.
The audit starts with server logs, not crawl tools. Crawl tools simulate — they tell you what they found, not what Googlebot actually did. Server logs show Googlebot’s real behaviour: which URLs it requested, what response it received, how long it waited, and how often it came back.
How to run a log-file crawl audit
- Export 14 days of server access logs. Most hosting panels offer this as a download.
If your logs use a standard
combinedformat, they include response codes, response times, and User-Agent strings. - Filter for
Googlebotusing your User-Agent field. The exact string is usuallyGooglebot/2.1orMozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html). - Group by URL pattern. You want to find the top 1% of URLs consuming the most crawl requests. These are your budget hogs.
- Classify each group. Facet navigation with infinite combinations (colour=red&size=large&material=cotton) can generate millions of crawlable URLs from a single template. These are the first candidates for noindex or canonical consolidation.
The most common budget waste I see on large e-commerce and publishing sites: pagination URLs with full indexing enabled, filtered views that create thousands of near-identical pages, and old promotional landing pages that still return 200 but have no internal links pointing to them.
2. Indexability: the four states a URL can be in
Google Search Console shows every URL in one of four states. Understanding what each state means tells you exactly what to fix:
Discovered — currently not indexed. Google found the URL (via a link or your sitemap) but
has not added it to the index yet. This usually means it is queued behind higher-priority
crawl candidates. If the page is important and the queue is long, improve its signals:
add internal links, ensure the XML sitemap includes it with a recent lastmod, and confirm
the URL returns a clean 200.
Crawled — currently not indexed. Googlebot visited and read the page but decided not to index it. This is the most actionable signal in Search Console. The causes are usually thin content, duplicate content, low E-E-A-T, or a canonical pointing somewhere else. For this state, the fix is never technical — it is content quality or canonical strategy.
Submitted and indexed. Working as intended. Monitor for drops.
Excluded by noindex. Intentional. Verify the exclusion is deliberate — a forgotten noindex on an important page will silently kill its rankings.
Soft 404s
A soft 404 is a page that returns a 200 status code but displays “no results”, “product not found”, or empty content. Googlebot treats these as thin pages and they consume crawl budget without contributing value. The fix: return a real 404 or 410 for genuinely removed content, and ensure empty-state pages are either noindexed or genuinely useful.
3. Canonicals: the eight mistakes that silently destroy indexation
The canonical tag tells Googlebot which version of a URL is the “true” version. When it is correct, it consolidates ranking signals to one URL and prevents duplicate content penalties. When it is wrong, it tells Googlebot to ignore the page you spent weeks building.
Here are the eight mistakes I encounter most often in audits:
Mistake 1: pointing every URL to the homepage
This happens most often in CMS migrations or when a template accidentally inherits the
homepage canonical. Every page on your site saying canonical=/ tells Google that every
page is the homepage. Google picks one and ignores the rest. Your blog posts, product
pages, and service pages vanish from the index.
Mistake 2: cross-domain canonical without ownership
If you set canonical=https://otherdomain.com/page on your page, you are telling Google
to index the other domain’s page instead of yours. This only works if you own or have
explicit permission from the other domain. Otherwise, Google ignores the signal.
Mistake 3: paginated series without self-referential canonicals
Page 2 of a category listing with canonical=/category/page-2 is correct. Page 2 with
canonical=/category (pointing to page 1) is wrong — it tells Google page 2 is a
duplicate of page 1. Each page in a paginated series should canonical to itself.
Mistake 4: trailing slash inconsistency
/about and /about/ are two different URLs. If your site serves both and they both
return 200, you need a redirect from one to the other. The canonical tag alone cannot
fix this — Googlebot will see two separate pages and may split signals between them.
Mistake 5: HTTPS vs HTTP mixed signals
If your site canonicalises HTTP URLs but serves HTTPS, or vice versa, Googlebot sees
contradictory signals. The canonical must match the version your server actually serves.
Redirect all HTTP to HTTPS and set canonical=https:// on every page.
Mistake 6: canonical pointing to a 404
A canonical tag pointing to a broken URL passes zero signals. Googlebot ignores it. This happens when sites migrate to new URL structures and forget to update canonical tags on the old pages. Audit your canonicals against your redirect map.
Mistake 7: relative canonical URLs
canonical=/about looks clean in the HTML but is technically ambiguous in some rendering
contexts. Always use absolute URLs: canonical=https://example.com/about.
Mistake 8: canonical in the body
Browsers move the canonical tag when they parse the DOM. If your page has a <link rel="canonical">
in the <body> instead of the <head>, browsers move it to the <head>. If the page is
rendered by JavaScript after load, the tag may never reach the <head> in time for
Googlebot’s first wave. Always put the canonical in the server-rendered HTML.
4. Redirects: chains cost more than you think
A redirect chain is one URL redirecting to another URL that redirects to a third URL.
Each hop consumes crawl budget and weakens the ranking signal passed through. A
three-hop chain from /old-page → /mid-page → /new-page passes roughly 85% of
the original link equity to /new-page. Ten hops might pass under 30%.
The most common chain I find in audits
/product/widget-blue → /products/widget (301 from old CMS) → /category/widgets (another 301) →
/widgets (redirect rule that caught this pattern) → 200.
This four-hop chain exists because redirects were added incrementally as the site migrated, migrated again, and changed URL structures a third time. Nobody ever audited the full chain end-to-end.
The one-hop rule
Audit every redirect in your chain. Use Screaming Frog’s “Custom -> Follow Redirect Chain”
mode or a log-file analysis. For every redirect, find the final destination URL. If it
is more than one hop away, replace the intermediate redirect with a direct redirect to the
final destination. A bulk 301 import from a migration tool will almost always leave
trailing-slash and case-sensitivity gaps — verify that sourceURL exactly matches the
URL Googlebot is actually requesting.
Redirect loops
A redirect loop — A → B → A, or A → A — is a crawler trap. Googlebot will hit the loop, consume crawl budget on it, and eventually mark the URL as unreachable. This often happens when a redirect rule and a canonical rule contradict each other, or when a site’s preferred domain setting and its redirect rule fight each other.
5. hreflang: the three rules that most sites break
hreflang tells Google which version of a page to serve to which language or region audience. It is required for any site with multiple language or regional variants.
The return-tag rule
Every page in a language cluster must list every other page in that cluster, including
itself. If you have /en/about, /de/about, and /fr/about, each of those three
pages must have three hreflang annotations: one for itself, one for the other language,
and one for the x-default.
Skipping the return tag on the German page but adding it to the English page creates an incomplete signal. Google ignores the entire hreflang cluster when the return tags are inconsistent.
Self-reference
Each page must include a hreflang pointing to itself. Without it, the cluster is asymmetric and Google may not trust the language signals.
x-default
The x-default hreflang specifies which page to serve when no language or region matches the user’s browser setting. This is usually the page that triggers a redirect or shows a language selector. Without it, Google guesses — and its guess may not match your business intent.
The ISO format rule
Use ISO 639-1 for language codes (en, de, fr) and ISO 3166-1 Alpha-2 for
region codes (US, GB, AU). The format is language-REGION — en-US, not
en_US or english-us. Hyphen, not underscore. Capital letters for the region,
lowercase for the language.
6. JavaScript rendering: Google’s two-wave system
Googlebot does not render JavaScript on the first pass. Its renderer (based on Chrome 114) fetches the initial HTML, indexes it, then queues the page for a second wave where it executes the JavaScript and re-renders. This second wave can happen hours to days after the first crawl.
For simple content sites with minimal JavaScript, this is irrelevant. For sites that render their primary content with React, Vue, or Angular, it is the difference between indexing in hours and indexing in a week.
How to audit JavaScript rendering
- Open Chrome DevTools on your live page.
- Disable JavaScript: press F12 → Console → type
javascript:void(0)or use the Network tab to block JS files. - View source (right-click → View page source). Find your primary content — the H1, the first paragraph, the main call-to-action. If it is not in the raw HTML, Googlebot’s first wave cannot see it.
- Re-enable JavaScript. Wait 5 seconds. View source again. If content appeared after JavaScript loaded, your site relies on second-wave rendering.
If the answer to step 3 is no but step 4 is yes, you are JavaScript-dependent. The implication: your content will index eventually, but slowly. On a news site with daily stories, this means your article may not appear in Google for 24-48 hours after publishing. A competitor with server-side rendering will out-rank you on timeliness.
Hydration traps
The most common JavaScript rendering failure I see: a page where the initial HTML contains the content (good for first wave) but the JavaScript hydration overwrites it with a blank state before the React component tree mounts (bad for any wave). This produces a “flash of content” where the server HTML shows briefly, then disappears when the client JavaScript takes over and finds no data.
The fix is to ensure the server-rendered HTML and the client hydration target the same DOM elements with the same content. Our JavaScript SEO 2026 guide covers hydration patterns, deferred content loading, and what Googlebot actually renders in its second wave.
7. Schema and structured data
Schema markup helps Google understand your page’s content and can trigger rich results in the search engine results page. But only when it is error-free.
Validate before launch
Run every page through the Rich Results Test
before you publish. This checks syntax, property completeness, and eligibility for
rich result types. A missing name on an Organisation schema, or an invalid datePublished
format, will silently disqualify the page from rich results without any error in Search Console.
Monitor Search Console after launch
After a page is live, Google will re-validate its schema periodically. If your schema was valid when you launched but your CMS updated its JSON-LD output and introduced a syntax error, Search Console will surface it under Enhancements. Check this monthly — schema errors are silent until they are not.
Schema that errors is worse than no schema
Google interprets a malformed schema differently depending on the error. Some errors cause the entire block to be ignored. Others cause Google to misinterpret the entity type, potentially applying the wrong rich result type or misclassifying the page. If your schema is complex and you are unsure, start with the minimal valid schema for your entity type and expand only when validation passes.
8. Sitemaps: one per content type
A sitemap is a map of your indexable URLs for search engines. It is not a ranking signal — Google has said so explicitly. But it is a crawl efficiency tool, especially for large sites where some URLs are only linked from JavaScript-rendered navigation.
The right sitemap structure
One sitemap per content type. A news site with articles, categories, and authors should have three sitemaps referenced from a sitemap index. An e-commerce site with products, categories, and blog posts should do the same. This allows you to prioritise the crawl budget Googlebot spends on each type.
Reference the sitemap index from robots.txt:
Sitemap: https://example.com/sitemap-index.xml
Reference each individual sitemap from the index:
<?xml version="1.0" encoding="UTF-8"?>
<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<sitemap>
<loc>https://example.com/posts-sitemap.xml</loc>
</sitemap>
<sitemap>
<loc>https://example.com/pages-sitemap.xml</loc>
</sitemap>
</sitemapindex>
Validate your sitemaps with our Sitemap Validator before submitting them to Google Search Console.
lastmod accuracy
Google uses the lastmod field to determine re-crawl frequency. If you set
lastmod to today’s date for every URL, Googlebot will re-crawl them every day
looking for changes — consuming your crawl budget on pages that changed last quarter.
The lastmod value should reflect the actual last publication or significant
update date, not the day you generated the sitemap.
9. Logs over crawl tools
Every SEO professional has a favourite crawler. Screaming Frog, Sitebulb, Ahrefs, Semrush — they are excellent tools. But they all simulate Googlebot. They do not show you what Googlebot actually did.
Server logs show you the ground truth: how many Googlebot requests per day, response time trends over two weeks, which URLs it requested most frequently, which returned errors on its second visit, and which parts of your site it visits least.
The most valuable log analysis I run for clients: finding the gap between what the crawl tool says is indexable and what Googlebot actually crawled in the same period. A sitemap that lists 8,000 URLs where Googlebot only crawled 3,000 tells me there is a crawl demand problem — Googlebot does not want to crawl the other 5,000.
Run a log analysis quarterly. Patterns compound: a redirect added in a migration that silently creates a chain, a pagination template that accidentally accumulated 20,000 URLs, a faceted navigation that is consuming 60% of your crawl budget — these problems are invisible in crawl tools and surface first in logs.
Frequently asked questions
Does a 301 redirect pass all ranking signals?
No. A 301 passes approximately 90-99% of link equity according to Google’s official statements. In practice, for most sites the difference is negligible. The problem is not the percentage — it is the chains. A single clean 301 passes virtually everything. Four chained 301s can drop you to 70%. Audit your chains.
My canonical is correct but Google indexed the wrong URL. Why?
Google sometimes ignores canonical tags when the signals conflict. If your page A
has canonical=A but 10,000 internal links point to URL B, Googlebot may decide
that B is the canonical version despite what the tag says. The fix is to ensure
internal links point to the canonical URL, not just the canonical tag.
How often does Googlebot re-crawl my pages?
It depends on crawl demand and update frequency. High-traffic pages with daily content changes can be re-crawled multiple times per day. Low-traffic pages with stale content might be crawled once a month. You can influence this through consistent publishing, internal linking, and XML sitemap updates — but there is no guarantee. Monitor your logs for crawl frequency changes after major content updates.
Should I submit a new sitemap every time I publish?
No. Submitting a sitemap triggers Googlebot to re-fetch it, but does not trigger
an immediate re-crawl of every URL in it. Googlebot will re-crawl based on its
own schedule. Set your sitemap to update lastmod values correctly and let
Googlebot’s normal crawl handle the rest. Only re-submit manually after a major
site migration or a complete URL structure change.
My site uses a CDN. Do I still need technical SEO?
Yes. A CDN fixes server response time and geographic distribution — critical for LCP on the Core Web Vitals side. But it does not fix canonical errors, JavaScript rendering problems, redirect chains, or crawl budget waste. CDN is an infrastructure layer, not a technical SEO strategy.
Wrap-up
A technical audit is not a one-time project. It is a quarterly habit. Every CMS update, migration, or redesign introduces new technical risk. Redirect chains accumulate. Canonical tags drift when templates change. JavaScript framework updates can break rendering. Build the crawl-first audit into your release cycle, monitor Search Console monthly for index coverage changes, and run a log analysis every quarter. The sites that consistently rank are the ones that catch the small failures before they become invisible ranking penalties.
Step-by-step
Pull server logs
Run a 14-day log file export. Split by Googlebot, Bingbot, and AI crawlers.
Map the crawl budget
Group URLs by status, depth, and staleness. Identify the 5% of URLs consuming 50% of crawl.
Audit indexability
Cross-reference indexed pages (Sitemaps + GSC) vs canonicals vs internal links. Find the gaps.
Fix redirects
Hunt redirect chains, loops, and 301 → 301 → 200 patterns. Cap at one hop.
Validate hreflang
Confirm return tags, x-default, and language-region codes against the ISO list.
Resolve rendering
Run a headless render of every template type. Confirm the rendered HTML contains your primary content. The full JavaScript rendering playbook — hydration traps, deferred content, and what Googlebot actually renders — is in our [JavaScript SEO 2026](/blog/javascript-seo-2026/) guide.
Frequently asked questions
The questions readers ask before they put the playbook to work.