Web crawling is software, called a crawler, spider or bot, downloading web pages and following their links to find more. Indexing is what happens next: the text is split into words, and each word is recorded with the pages that contain it, in an inverted index, so a search finds matching pages without rereading the web.
Search engines, web archives and AI companies all run crawlers, and they behave differently. This guide covers how a crawler works as software, what an index stores, how Bingbot, Common Crawl and AI crawlers such as GPTBot, ClaudeBot and PerplexityBot differ and how to control each one, then gives an engine-neutral checklist and a way to read your server logs. For Google's own pipeline (Googlebot, rendering, canonicals and Search Console), read how the Google search engine works.
Crawling and indexing: what each step does
The two words travel together, but they are separate jobs, often run by separate systems, and a page can pass one and fail the other.
| Question | Crawling | Indexing |
|---|---|---|
| What it answers | Which pages exist, and what do they contain right now? | Which pages match this word or phrase? |
| What does the work | A crawler requesting URLs over HTTP | An indexer turning fetched pages into terms |
| What it produces | A store of downloaded pages and a list of new links | An inverted index, plus stored data about each page |
| What you control | robots.txt, links, sitemaps, status codes, server speed | noindex, duplicate URLs, the content itself |
| How it goes wrong | Blocked, unreachable, too slow, or never linked | Fetched, but treated as a duplicate, excluded or not useful |
The order matters. A page has to be fetched before it can be indexed, so the crawl is the first place to look when a page is missing from search results. The controls are separate too. Blocking a URL in robots.txt stops the engine reading it, not listing it; to keep a page out of results you use noindex, and the engine has to be allowed to fetch the page to see that rule. Bing's webmaster guidelines put it plainly: robots.txt controls crawl access, not indexing.
How a web crawler works, step by step
Every crawler, from a search engine's fleet to a small script, runs the same loop. The textbook description in Introduction to Information Retrieval (Manning, Raghavan and Schütze, Cambridge University Press) follows Mercator, a crawler design that became the basis of several research and commercial crawlers:
- Start from seeds. The crawl begins with a seed set of known URLs. For a search engine, that is every URL it already knows about, plus sitemaps and URLs sites submit.
- Take the next URL from the frontier. The URL frontier holds every URL not yet fetched, in priority order.
- Check robots.txt, then fetch. The crawler resolves the host name with DNS, checks the host's robots.txt rules and downloads the page over HTTP.
- Parse. It extracts the text for the indexer, and the links with their anchor text.
- Filter and deduplicate. Each link is made absolute, run through URL filters and dropped if it is already queued or was fetched recently. A page whose content was already seen at another URL is flagged as a copy.
- Queue and repeat. New URLs join the frontier with a priority. In continuous crawling, the fetched URL goes back in as well, to be fetched again later.
The loop is simple; the scale is not. The same textbook works out that fetching a billion pages in a month means several hundred fetches every second, sustained, while staying polite to every site, surviving malformed pages and avoiding traps. The parts that matter most to a site owner are the frontier, duplicate detection and the recrawl schedule.
The URL frontier decides what is fetched next
The frontier is where a crawler's judgement lives. It orders URLs on two considerations. The first is priority: pages that are useful and change often should be fetched often, so priority combines a quality estimate with how often the page has changed between past visits. Change alone is not enough, because many spam pages change completely on every fetch. The second is politeness.
Many links on a page point to the same host, so a plain priority queue would fire a burst of requests at one server. Mercator-style frontiers prevent that by design: a set of back queues, each holding URLs from a single host, a record of when each host may next be contacted, and one open connection per host at a time. A common heuristic sets the wait before the next request to about ten times as long as the last fetch from that host took, so a server that slows down automatically receives fewer requests.

Open-source crawlers ship with the same instincts. A new Scrapy project waits one second between requests to the same domain (DOWNLOAD_DELAY) and obeys robots.txt (ROBOTSTXT_OBEY) out of the box. Sites can push back in two ways:
- HTTP 429 Too Many Requests, defined in RFC 6585, optionally with a
Retry-Afterheader saying how long to wait. A 503 can carryRetry-Aftertoo. Common Crawl's crawler uses an adaptive back-off when a site answers 429 or 5xx, and Apple says Applebot's crawl rate adjusts automatically when a site slows down or returns errors. Crawl-delayin robots.txt, a non-standard line asking for a pause, in seconds, between requests. Support varies by crawler (see the table below). Bing reads it as one URL per window of 1 to 20 seconds, soCrawl-delay: 5caps Bingbot at 17,280 URLs a day.
That cap is why a delay is a blunt tool: at 17,280 URLs a day, a site with 100,000 URLs needs almost six days for Bingbot to fetch each page once. Bing's own help recommends against it and points to Crawl Control in Bing Webmaster Tools, which sets a crawl rate for each hour of the day instead.
robots.txt: the rules a crawler reads before fetching
robots.txt is where a site states its rules for bots. Martijn Koster defined the Robots Exclusion Protocol in 1994, and the IETF published it as RFC 9309, a standards-track document, in September 2022. What the standard says, and what a compliant crawler does:
- Location. The file lives at
/robots.txtat the top of each host, UTF-8 encoded, as plain text. The file onwww.example.comsays nothing aboutshop.example.com. - Groups. Rules sit under one or more
User-agentlines. A crawler looks for a group naming its product token, matching case-insensitively; if none exists, it obeys the*group; if there is no*group either, nothing is disallowed. - Matching. The most specific rule, the one with the most characters, wins. If an
Allowand aDisallowrule are equally specific,Allowwins.*matches any run of characters and$marks the end of a path. - Errors. If robots.txt answers with a 4xx status, the crawler may fetch anything. If it answers with a 5xx or the server is unreachable, the crawler must assume everything is disallowed.
- Caching and size. Crawlers should not use a cached copy for more than 24 hours, and must parse at least the first 500 KiB.
- Not security. The RFC states that the rules are not a form of access authorization, and that listing a path in robots.txt makes it public. Protect private areas with authentication.
# Rules for every crawler without its own group
User-agent: *
Disallow: /cart/
Disallow: /search/
Allow: /search/help/
Sitemap: https://www.example.com/sitemap.xml
In this file, /search/help/ stays crawlable because Allow: /search/help/ is the longer, more specific match. Anything beyond User-agent, Allow and Disallow is an extension a crawler may or may not read. Sitemap is the widely supported one. Crawl-delay is not in the standard, which is why Google ignores it while Bing honours it. Google's own reading of the file, including how it treats errors, is covered in how Google crawls a page.
Duplicates and spider traps
The web is full of copies: the same article with and without tracking parameters, print versions, mirrors, syndicated posts. The textbook cites estimates that as many as 40% of web pages duplicate other pages. Crawlers and indexers deal with them at two levels:
- Duplicate URLs. Before a link enters the frontier, it is normalized (a relative link becomes an absolute URL) and checked against the URLs already queued or fetched.
- Duplicate content. After a fetch, the page gets a fingerprint, a short digest of its content, and pages with equal fingerprints are copies. Exact fingerprints miss near-duplicates, such as two pages identical except for a timestamp, so engines use shingling: they compare the sets of overlapping four-word runs in two pages, and pages above a similarity threshold are indexed once.
Your side of the deal is one URL per piece of content, with redirects and rel="canonical" saying which URL you prefer. Google's canonical rules are in the Google guide.
Crawlers also have to survive spider traps: URL spaces that never end, such as a calendar with a "next month" link forever, or filters and sort orders that multiply into millions of URLs. Some traps are built to mislead crawlers; many are accidents of site development. A crawler defends itself with URL filters and limits per host. For your site, the cost is that its attention goes to worthless URLs instead of your real pages.
Recrawling keeps the copy fresh
An index is a snapshot, and the web keeps changing. A continuous crawler puts fetched URLs back in the frontier and tries to revisit each page at a rate that approximates how often it changes, so a news home page is fetched far more often than a policy page last edited years ago. Three mechanisms make revisits cheaper for both sides:
- Conditional requests. The crawler sends
If-None-Matchwith the page's lastETag, orIf-Modified-Sincewith itsLast-Modifieddate. If nothing changed, the server answers304 Not Modifiedinstead of sending the page again (RFC 9110). Google's crawlers support both headers and Common Crawl supports conditional GET. - Sitemap
lastmod. The Sitemaps protocol lets you state when each URL last changed. It describeschangefreqas a hint that crawlers may weigh, not a command they follow. - Push notifications. IndexNow tells participating engines the moment a URL changes (covered below).
What a search index is and what it stores
A search engine does not search the web when you type a query. It searches its index, a data structure built in advance from the crawled pages. The core of it is the inverted index: instead of listing the words on each page, it lists, for each word, the pages that contain it, the way the index at the back of a book lists pages for each topic.
Building one takes four steps:
- Collect the documents. The crawler has done this.
- Tokenize each one. Tokenization chops the text into tokens, usually words, and throws away characters such as punctuation.
- Normalize the tokens into terms. Lowercasing makes
Quickmatchquick. Stemming reducesfoxestofox, andorganizesandorganizingto one form. Synonym rules can mapleaptojump. The same text analysis runs on every query, so a search for "Foxes leap" looks upfoxandjump. - Invert. Sort the list of term and document pairs, merge repeats, and split the result into a dictionary of terms and, for each term, a postings list of the documents that contain it.
Three one-line pages show the result. Page 1 reads "Crawlers fetch pages", page 2 "Indexes store pages" and page 3 "Crawlers respect robots.txt":
| Term | Postings (page: word position) |
|---|---|
| crawler | 1: 1 · 3: 1 |
| fetch | 1: 2 |
| index | 2: 1 |
| page | 1: 3 · 2: 3 |
| respect | 3: 2 |
| robots.txt | 3: 3 |
| store | 2: 2 |
A query for "crawler pages" looks up two postings lists and intersects them: only page 1 is on both, and no page had to be read to find it. Storing positions lets the engine answer phrase queries by checking that two terms sit side by side, and postings usually record how often each term occurs, which ranking formulas use.

Older systems dropped very common words such as "the" and "of" from the index. The textbook notes that web search engines generally do not use stop lists: titles such as "To be or not to be" consist entirely of them.
What else an index keeps about a page
The word index is only part of the record. Depending on the engine, it also holds:
- the page's title, description, language and other metadata;
- its outgoing links with their anchor text, which the crawler passes to the indexer for use in ranking;
- fetch details: the status code, when the page was fetched, and the
ETagor date needed for the next conditional request; - the content fingerprint used to spot copies, and which URL was chosen to represent a set of duplicates.
At web scale the index is split across many machines. The common approach is to partition by document: each machine indexes a subset of pages, every query goes to all of them, and their top results are merged. When someone searches, the engine runs the query through the same tokenization, fetches and combines the postings, then ranks the matches. Ranking is where engines differ most; for Google's approach, see how Google ranks results. AI assistants with search work from an index too: Bing's guidelines state that its Copilot experiences rely on the same crawling, indexing and ranking foundation as classic Bing search. For Google's AI answers, see the latest SEO trends.
How search engines and AI bots crawl differently
Every major operator documents its crawlers, and the documentation shows four kinds of bot that are easy to confuse:
- Search crawlers fetch pages for a search index: Googlebot, Bingbot, Applebot, OAI-SearchBot, Claude-SearchBot and PerplexityBot.
- Training crawlers collect pages that may be used to train AI models: GPTBot and ClaudeBot. Google and Apple use control tokens instead of separate crawlers: Google-Extended and Applebot-Extended.
- User-triggered fetchers load a page because a person asked an assistant about it: ChatGPT-User, Claude-User and Perplexity-User.
- Archive crawlers build public datasets: Common Crawl's CCBot.
| Bot | Operator | What it is for | What to know |
|---|---|---|---|
| Googlebot | Google Search | Ignores Crawl-delay; details in the Google guide | |
| Bingbot | Microsoft | Bing search, Copilot and Bing's grounding API | Honours Crawl-delay; renders pages with the current stable Microsoft Edge |
| Applebot | Apple | Spotlight, Siri and Safari; may train Apple models | Ignores Crawl-delay; follows Googlebot rules if no Applebot group exists |
| CCBot | Common Crawl | Open web archive | Honours Crawl-delay; does not run JavaScript |
| GPTBot | OpenAI | Crawling that may be used to train OpenAI models | Independent of OAI-SearchBot |
| OAI-SearchBot | OpenAI | Pages shown in ChatGPT search | Opted-out sites can still appear as navigational links |
| ChatGPT-User | OpenAI | Pages a ChatGPT user asks for | OpenAI says robots.txt rules may not apply |
| ClaudeBot | Anthropic | Content that may be used to train Anthropic's models | Honours Crawl-delay |
| Claude-SearchBot | Anthropic | Search results in Claude | Independent of ClaudeBot |
| Claude-User | Anthropic | Pages a Claude user asks for | Can be disallowed in robots.txt |
| PerplexityBot | Perplexity | Perplexity search results, not model training | Perplexity publishes its IP ranges |
| Perplexity-User | Perplexity | Pages a Perplexity user asks for | Perplexity says it generally ignores robots.txt |
| Google-Extended | Token only: Gemini training and grounding | No crawler of its own; no effect on Google Search | |
| Applebot-Extended | Apple | Token only: training of Apple's foundation models | Disallowing it does not stop Applebot crawling for search |
Sources for each row: Bing, Apple, Common Crawl, OpenAI, Anthropic, Perplexity and Google, as documented in September 2026.
Bing also accepts IndexNow pushes (below), and its guidelines define two meta directives for AI use: noarchive keeps a page's content out of Copilot answers and grounding results, and nocache limits Copilot to the URL, title and snippet.
Common Crawl is a non-profit, founded in 2007, that crawls the web and publishes the result as a free, open archive. As of September 2026, its site describes more than 300 billion pages collected over 15 years, with 3 to 5 billion new pages added each month, and says the archive has been cited in over 10,000 research papers. CCBot is built on Apache Nutch, checks robots.txt before fetching and samples each site rather than archiving it whole.
AI crawlers are split by purpose, which is what makes a precise policy possible (next section). Whether a crawler runs JavaScript is often not documented at all, so assume some bots see only the HTML your server sends.
How to control each crawler with robots.txt
Because each bot answers to its own user-agent token, one robots.txt can set a policy per purpose. This example keeps every search crawler, opts out of AI training and the Common Crawl archive, and keeps all bots out of the cart:
# Search engines and AI search
User-agent: Googlebot
User-agent: Bingbot
User-agent: Applebot
User-agent: OAI-SearchBot
User-agent: Claude-SearchBot
User-agent: PerplexityBot
Disallow: /cart/
# AI model training and open archives
User-agent: GPTBot
User-agent: ClaudeBot
User-agent: Google-Extended
User-agent: Applebot-Extended
User-agent: CCBot
Disallow: /
# Everyone else
User-agent: *
Disallow: /cart/
Sitemap: https://www.example.com/sitemap.xml
What decides whether a file like this works:
- Tokens are independent. OpenAI, Anthropic and Perplexity each describe their bots as separate settings. Google-Extended and Applebot-Extended change how Google and Apple may use what Googlebot and Applebot fetch; Google states that Google-Extended does not affect inclusion or ranking in Google Search.
- Changes are not instant. RFC 9309 lets crawlers cache robots.txt for up to 24 hours, and OpenAI and Perplexity both say their systems can take about a day to reflect an edit.
- Every host needs its own file. Anthropic's documentation reminds site owners to repeat an opt-out on every subdomain.
- User-triggered fetchers play by different rules. OpenAI says robots.txt rules may not apply to ChatGPT-User, and Perplexity says Perplexity-User generally ignores them, because a person asked for the page. Anthropic lets you disallow Claude-User like its other bots.
- Page-level rules still apply. Bing and Apple support
noindex. Apple also honoursnosnippetto keep content out of the AI-generated answers in Siri and Search.
Important
robots.txt is a published request, not enforcement. User agents are easy to fake, as Bing warns and Common Crawl has seen with crawlers posing as CCBot. To actually stop a bot, block it at your firewall or CDN, and use the operator's published IP ranges to tell the real crawler from impostors. Anthropic notes that blocking its IP addresses can stop its bots reading your robots.txt, so it asks site owners to opt out in robots.txt instead.
WAF rules and rate limiting at the edge are part of our hosting and maintenance service, for when a request is not enough.
A shared vocabulary is on its way. The IETF's AI Preferences working group is standardizing a way to state preferences such as allowing search but not AI training, attached through a new Content-Usage rule in robots.txt or an HTTP header of the same name. As of September 2026 both documents are still Internet-Drafts, so each company's own token is what its crawlers read today.
Push instead of waiting: how IndexNow works
Crawling is pull: the engine decides when to come back. IndexNow adds push. Microsoft Bing and Yandex created the protocol in October 2021 so that a site can tell search engines the moment a URL is added, updated or deleted. The protocol takes three steps:
- Publish a key. Generate a key of 8 to 128 characters (letters, digits and hyphens) and host it as a UTF-8 text file named after the key, preferably at the root:
https://www.example.com/<key>.txt. - Send changed URLs to one endpoint, either one URL as a GET request with
urlandkeyparameters or a JSON POST of up to 10,000 URLs. - Let the engines share it. The receiving engine fetches your key file to confirm you control the host, and participating engines agree to share submitted URLs with each other.
POST /indexnow HTTP/1.1
Host: api.indexnow.org
Content-Type: application/json; charset=utf-8
{
"host": "www.example.com",
"key": "4f1c9e7a2b8d4e6f",
"urlList": [
"https://www.example.com/new-page/",
"https://www.example.com/updated-page/"
]
}

Where it fits, according to the IndexNow FAQ:
- Use it with a sitemap, not instead of one. IndexNow is for new and changed pages; the sitemap remains the complete inventory.
- A 200 response means received, not indexed. A 202 means the key is still being checked. Every submitted URL counts toward your site's crawl quota, and the same URL should not be resubmitted many times a day without a real change.
- Check who listens. As of September 2026 the FAQ lists endpoints for Bing, Yandex, Naver, Seznam.cz, Yep and Amazon. Google is not among them, so Google still learns about changes from links and sitemaps.
- Check your platform first. Many CMSs support IndexNow through plugins, and Cloudflare offers it natively, so you may not need to write code.
Read your server logs to see which bots crawl what
Webmaster consoles show you one engine's view. Your access logs show every bot that touched the site, including the ones with no console at all. Apache's Combined Log Format and nginx's predefined combined format, its default, both record the client IP, the time, the request line, the status code and the User-Agent header. That is enough to answer the three questions that matter.
# Requests per crawler (split on quotes, the User-Agent is field 6)
awk -F'"' 'match(tolower($6), /googlebot|bingbot|applebot|oai-searchbot|gptbot|chatgpt-user|claude-searchbot|claudebot|claude-user|perplexitybot|perplexity-user|ccbot/) { print substr(tolower($6), RSTART, RLENGTH) }' access.log | sort | uniq -c | sort -rn
# Status codes one crawler received
awk -F'"' '$6 ~ /bingbot/ { split($3, s, " "); print s[1] }' access.log | sort | uniq -c
# The paths GPTBot requests most
awk -F'"' '$6 ~ /GPTBot/ { split($2, r, " "); print r[2] }' access.log | sort | uniq -c | sort -rn | head -20
What the numbers usually mean:
| What you see in the logs | What it usually means | What to do |
|---|---|---|
| Most bot requests go to parameter, sort or date URLs | A spider trap or faceted navigation | Link to clean URLs; disallow worthless patterns in robots.txt |
| Many 404 or 410 responses for one bot | Old links or an outdated sitemap | Fix internal links, redirect moved pages, update the sitemap |
| Frequent 429 or 5xx responses | The server is shedding load; crawlers back off | Add capacity or caching before blocking bots |
| 304 responses on revisits | Conditional requests are working | Nothing: this saves bandwidth on both sides |
| Important pages never requested | Not linked, or not in the sitemap | Link them from crawled pages, list them, notify IndexNow |
| A search engine's user agent from an unexpected network | A fake bot | Verify the IP before allowing or blocking it |
A user agent proves nothing on its own. The reliable check is a reverse DNS lookup on the IP from your log, then a forward lookup on the name it returns: both must point at each other. Genuine Bingbot addresses resolve to names ending in search.msn.com, Applebot to applebot.apple.com and CCBot to crawl.commoncrawl.org. Apple's documentation uses this example:
host 17.58.101.179
host 17-58-101-179.applebot.apple.com
OpenAI, Perplexity and Anthropic publish their crawlers' IP addresses, so you can match against those lists. Googlebot's version of the check is in the Google guide. Reading logs alongside a crawler and Search Console is how our SEO service audits the crawl, render and index layers of a site.
A bot-friendly checklist for any search engine
These steps help every crawler, not one engine:
- Serve the main content in the HTML. Bingbot and Applebot can render JavaScript, but CCBot does not run it and many bots do not say either way. Server-rendered or static HTML reaches all of them.
- Link every page you want found from pages that are already crawled, with ordinary
<a href>links, so it enters the frontier. - Publish an XML sitemap of canonical URLs with accurate
lastmoddates, and name it in robots.txt with aSitemap:line so every crawler can find it. - Keep robots.txt short and deliberate. Block only what has no search value (carts, internal search results, endless filters), never the CSS and JavaScript your pages need to render, and make sure the file answers 200 or 404: a 5xx tells compliant crawlers to stop.
- Return honest status codes. 200 for real pages, 301 for moved ones, 404 or 410 for removed ones, and 429 or 503 with
Retry-Afterwhen crawlers must slow down. - Keep one URL per piece of content. Redirect duplicates, declare
rel="canonical"and keep tracking parameters out of internal links. - Support conditional requests. Send
ETagorLast-Modifiedso unchanged pages can be answered with a 304. - Notify engines on change with IndexNow or your CMS's integration, and keep the sitemap current for everyone else.
- Set your AI policy per token, not with one blanket rule, and repeat it on every subdomain.
- Read the logs every month: requests per bot, status codes per bot, and important paths no bot has requested.
Web crawling and indexing software you can run yourself
The same parts are available as open-source software, for site search, an internal document search or a crawl of your own:
| Software | What it is | Typical use |
|---|---|---|
| Apache Nutch | An extensible, scalable, production web crawler built on Hadoop data structures | Large batch crawls; CCBot is based on it |
| Heritrix | The Internet Archive's web-scale, archival-quality crawler | Web archiving |
| Apache StormCrawler | An SDK for low-latency, distributed crawlers on Apache Storm | Continuous crawling |
| Scrapy | A Python framework for crawling sites and extracting structured data | Focused crawls and scraping |
| Apache Lucene | A full-text search library in Java, with faceting and vector search | Search built into an application |
| Solr, OpenSearch, Elasticsearch | Search servers built on Lucene | Site, document and log search |
For the search box on your own website you rarely need a crawler at all. Your CMS or build step already knows every page and can feed the index directly, without waiting for a recrawl. A crawler earns its place when the content lives on sites you do not control.


