Skip to content
masterclassBuddyTech Buzz5 fresh blogs · 5:00 AM IST

System Design blueprint · Search and data infrastructure

Web crawler at scale

Discovers, fetches, deduplicates and stores billions of web pages, then recrawls them as they change. It must never overload a host, ignore robots.txt, or loop forever in crawler traps.

Steps
8
Subjective questions
33
Objective questions
33

The problem and the outcome

Problem: Search engines, archives and AI data teams need fresh copies of a huge, changing web. Naive crawlers hammer small sites, refetch the same content and get stuck in infinite URL spaces.

Outcome: Fetch capacity goes to new or changed pages that matter, every host is crawled within its limits, and duplicate or trap URLs are filtered before they cost bandwidth or storage.

Architecture

Seed URLsoperator input01Recrawl schedulerchange-rate model08URL frontierpriority queues02Per-host queuespoliteness gate03robots.txt cacheper host, TTLFetcher poolasync HTTP04DNS resolverlocal cacheParserlink extraction05Near-dup checkSimHash07Trap filterURL rules, depthURL-seen setBloom + KV store06Page storeWARC in objectsCrawl metadatafetch historyseed URLsprioritized URLscheck ruleshost readyresolve hostbody + headers429/5xx backoffstatus, ETag, timeextracted linksnormalized URLsunseen URLs onlypage textunique contentdup: link canonicalchange historydue URLs

How it works, step by step

  1. Operators load seed URLs (curated lists, sitemaps, previous crawl) into the frontier with an initial priority.
  2. The frontier holds URLs in priority queues scored by signals such as link importance, domain quality and freshness need, and hands them to host-keyed back queues.
  3. Each host has one back queue and a next-allowed-fetch time; the gate releases a URL only when the host's delay has passed and the cached robots.txt allows the path, refetching robots.txt when its TTL expires.
  4. Async fetchers resolve hostnames through a local DNS cache, send conditional GETs with If-None-Match or If-Modified-Since, enforce size and time limits, and report 429 or 5xx responses so the host is slowed down.
  5. The parser extracts links and canonical tags, normalizes URLs (lowercase host, drop fragments, sort or strip tracking parameters) and passes them through trap rules for depth, length, repeated path segments and per-host URL budgets.
  6. Normalized URLs are checked against a Bloom filter backed by a sharded key-value store, and only unseen URLs are added to the frontier.
  7. Page text is fingerprinted with an exact hash and SimHash; near-duplicates are recorded as aliases of a canonical page, while unique content is written as WARC records to object storage.
  8. The recrawl scheduler reads fetch history, estimates each URL's change rate and value, and re-enqueues URLs when they are due, backing off on pages that rarely change.

Tech stack

  • Go or Rust async fetchers with HTTP/2 support
  • Kafka for frontier partitions keyed by host
  • Redis or RocksDB for per-host back queues and timers
  • Bloom filters plus Cassandra or RocksDB for the URL-seen set
  • Object storage (S3-compatible) with WARC files
  • SimHash fingerprints indexed by banded bit blocks
  • Local caching DNS resolver such as Unbound
  • Apache StormCrawler or Nutch as reference designs

Key design decisions

  • Partition the crawl by host hash so one worker owns each host; politeness then becomes a local timer instead of a distributed lock.
  • Split the frontier into priority front queues and per-host back queues (Mercator style) so importance and politeness are handled separately.
  • Use a Bloom filter as a fast negative check and confirm hits in a persistent store, accepting a small chance of skipping a new URL in exchange for memory savings.
  • Detect near-duplicates with 64-bit SimHash and a small Hamming distance threshold rather than exact hashing, because boilerplate and ads change between copies.
  • Schedule recrawls from observed change frequency and page value rather than a fixed interval, and use conditional requests to make unchanged refetches cheap.

Common mistakes

  • Keying politeness on hostname alone while many hostnames share one IP or hosting provider, which still overloads the server.
  • Calendar pages, session IDs in URLs and faceted navigation generating unbounded URL spaces that exhaust host budgets.
  • Treating a 5xx on robots.txt as permission to crawl; RFC 9309 says to assume the site is fully disallowed in that case.
  • Skipping URL normalization so the same page enters the frontier under many spellings and wastes fetches.
  • Not capping response size and redirect chains, letting a few hosts tie up fetcher connections.

What to measure

  • Pages fetched per second and per fetcher, split by status code
  • Share of fetches that were duplicates, near-duplicates or 304 Not Modified
  • Freshness: median age of stored copies for high-priority URLs
  • Per-host request rate and count of 429 or 503 responses
  • Frontier size and share of URLs dropped by trap rules

Most-asked interview questions

Subjective questions 33

1How would you design the URL frontier so it respects politeness and still keeps thousands of fetchers busy?Asked almost every time

I would use a two-level design. Front queues are ordered by priority, computed from link signals, domain quality and freshness need. A router moves URLs from front queues into back queues, one per host, and each back queue has a next-allowed-fetch timestamp in a min-heap. A fetcher pops the host whose time has come, takes one URL, and the host's time is pushed forward by its crawl delay, adjusted up after 429 or 5xx responses. Because there are millions of hosts, there are always ready hosts, so fetchers stay busy without any single host being hit hard. I would shard by host hash so each host lives on exactly one worker, which avoids distributed locking. I would also apply limits per IP, since many small sites share servers.

2How do you avoid crawling duplicate URLs and storing duplicate content at billions of pages?Asked almost every time

There are two separate problems. For URLs, I normalize first: lowercase scheme and host, remove fragments and default ports, resolve relative paths, and strip known tracking parameters. Then I check a Bloom filter; a miss means definitely new, a hit is confirmed in a sharded key-value store, so memory stays small. For content, exact hashes catch identical bodies, but most duplicates differ by ads or timestamps. So I extract main text, compute a 64-bit SimHash, and treat pages within a few bits of Hamming distance as near-duplicates. To search quickly, I split the fingerprint into bands and index each band, so candidates share at least one band. Duplicates are stored as aliases pointing to a canonical page, and rel=canonical tags are used as a hint, not trusted blindly.

3Walk me through the high-level architecture of a large-scale web crawler.Asked almost every time

I split it into a loop of stages. Seeds go into a URL frontier. The frontier has priority queues and per-host back queues. A politeness gate releases a URL only when the host's delay has passed and robots.txt allows the path. Async fetchers use a local DNS cache and send conditional GETs. The parser extracts and normalizes links and applies trap rules. A URL-seen check, a Bloom filter backed by a sharded key-value store, decides which links enter the frontier. Content is fingerprinted for exact and near duplicates, and unique pages are written as WARC records to object storage. A recrawl scheduler reads fetch history and re-enqueues URLs as they come due. Each stage scales out independently, and work is partitioned by host.

4Give a back-of-envelope estimate for crawling one billion pages per month.Asked almost every time

A 30-day month is about 2.6 million seconds, so one billion pages means roughly 385 fetches per second on average. I would plan for two to three times that at peak, because of retries and uneven host availability. Bandwidth and storage depend on the average page size, so I state it as an assumption. If pages average 100 KB uncompressed, that is about 38 MB/s, around 300 Mbps sustained, and about 100 TB of raw HTML per month before compression. Gzip in WARC typically shrinks HTML several-fold. Each fetch spends most of its time waiting on the network, so async I/O lets one machine hold thousands of open connections. The real limits are politeness and DNS, not CPU.

5How do you estimate a page's change rate and schedule its recrawls?Asked almost every time

I model each page's changes as a Poisson process with rate λ. Each fetch tells us whether the content changed since the last fetch, using a 304 response, an unchanged hash or a SimHash distance. From that history I estimate λ, with estimators that correct for changes missed between visits. The next recrawl time comes from λ and the page's value, such as importance, traffic or how often it links to new URLs. Pages that rarely change are backed off exponentially up to a maximum interval. Volatile, high-value pages are revisited sooner. Research by Cho and Garcia-Molina shows that pages which change too fast to keep fresh should not get unlimited budget. Sitemap lastmod, feeds and push signals can trigger early recrawls.

6What are crawler traps and how would you defend against them?Very often asked

A trap is any URL space that generates effectively infinite pages: calendars with next-month links forever, session IDs in URLs, faceted filters combining endlessly, or relative-link bugs that keep growing the path. Some are malicious, most are accidental. I defend in layers. Normalization removes session parameters. Rule filters reject URLs over a length limit, with too many query parameters, or with repeated path segments. Each host gets a crawl budget tied to its importance, so a trap can only waste that host's share. I track depth from seeds and the ratio of new unique content per host; if a host keeps producing near-duplicate pages, I lower its priority. Finally, I monitor hosts whose discovered URL counts grow abnormally fast and review or block patterns.

7How do you partition the crawl across many crawler machines?Very often asked

I partition by host, or by registrable domain, using consistent hashing. Each host is then owned by exactly one node, so its back queue, next-allowed-fetch time and robots.txt cache stay local. Politeness can be enforced without distributed locks. When a node joins or leaves, only about 1/N of the hosts move. Links the parser finds are routed to the owning node of their host, usually in batches through a message bus, to keep cross-node traffic cheap. Very large hosts can be a hotspot, but politeness caps per-host throughput anyway, so that is rarely a CPU problem. Virtual nodes even out how many hosts each machine owns. Ownership changes must hand over queue state, or the new owner must rebuild it from durable storage.

8How should the crawler cache robots.txt, and what does RFC 9309 say about 4xx responses and file size?Very often asked

robots.txt is cached per host, keyed by scheme, host and port, because each origin has its own file. RFC 9309 says crawlers should not use a cached copy for more than 24 hours, unless the file is unreachable. So I set a TTL of 24 hours or less and refetch it when the TTL expires. A 4xx response, such as 404, means the file is unavailable, and the crawler may access any resource. Redirects should be followed for at least five hops. Crawlers must parse at least 500 KiB of the file. Rules are matched by the longest matching path. If an Allow and a Disallow rule are equally specific, Allow wins. Crawl-delay is not part of the standard, but many crawlers honour it as a courtesy.

9How does the crawler adapt its rate when a host returns 429 or 5xx errors?Very often asked

Each host record stores a crawl delay, and the gate uses it to set the next-allowed-fetch time. On a 429, I honour the Retry-After header if it is present. Otherwise I apply multiplicative backoff, for example doubling the delay up to a cap. Repeated 5xx responses or timeouts also increase the delay. After sustained failures, the host is paused for a cool-down period. When responses are healthy again, the delay shrinks slowly, which is the AIMD pattern from congestion control. I also scale the delay with observed response time, because a slow server is a stressed server. Failed URLs are re-enqueued with a retry count, and they are dropped or parked after a limit. The host never sees a retry storm.

10Which URL normalization rules are safe, and which are risky?Very often asked

Safe rules follow RFC 3986 equivalence. Lowercase the scheme and host. Remove the default port, such as :80 for http. Resolve dot segments. Normalize the percent-encoding of unreserved characters. Drop the fragment, because it is never sent to the server. Risky rules change meaning on some sites. Paths can be case-sensitive. Some query parameters actually select content, so I only strip known tracking parameters like utm_* or session IDs, and I learn per-host rules where possible. Sorting query parameters is usually safe, but not always. Removing a trailing slash or a www prefix should be verified, for example by the redirects you observe. Over-normalizing loses pages. Under-normalizing wastes the crawl budget on duplicates.

11How do you size the Bloom filter for the URL-seen set, and what happens as it fills up?Very often asked

The false-positive rate is about (1 − e^(−kn/m))^k, where n is the number of items, m is the number of bits and k is the number of hash functions. The optimal k is (m/n)·ln 2. A 1% false-positive rate needs about 9.6 bits per element, and 0.1% needs about 14.4. A false positive means an unseen URL is skipped, so the cost is lost coverage, not a correctness bug. If more URLs go in than planned, the rate climbs fast. So I size for the expected URL count with headroom, shard the filter by URL hash, and monitor its fill ratio. For long-running crawls I use scalable Bloom filters or rotate by generation. The backing key-value store holds the authoritative record.

12How do you prioritize URLs in the frontier without starving parts of the web?Very often asked

Each URL gets a score from several signals. Examples are link-based importance such as an approximate PageRank, domain quality, depth from the seeds, freshness need for recrawls and business priorities. The score maps to one of several front priority queues. A biased selector picks from higher queues more often but still serves lower ones, so nothing starves. Per-host back queues add fairness, because no single host can dominate. I also cap the number of URLs per host and per domain admitted into each round. Without these caps, a giant site or a trap could crowd out the long tail. Priorities are recomputed periodically, because link graphs change as the crawl discovers more pages.

13A fetcher node crashes in the middle of a batch. How does the system recover without losing or duplicating too much work?Very often asked

The frontier is durable, either a replicated log or a persistent queue with periodic checkpoints. A fetcher leases a URL instead of deleting it. When the fetch result is committed, the lease is acknowledged. If the node dies, the leases expire and the URLs become available again. This gives at-least-once fetching. A few pages may be fetched twice, which is acceptable because writes are idempotent. The WARC record is keyed by URL and fetch time, and dedup absorbs repeats. The per-host next-allowed-fetch time must also be persisted or conservatively reset, so recovery does not hit hosts too fast. Host ownership moves to another node through consistent hashing. Partially written WARC files are closed or discarded, and the index points only to committed records.

14Sketch the core data model for the crawler.Very often asked

There are four main entities. A URL record is keyed by a hash of the normalized URL. It holds the URL, host ID, canonical URL, discovery source, depth, priority, status, last fetch time, HTTP status, ETag, Last-Modified, content hash, SimHash, estimated change rate and next due time. A host record holds the robots.txt rules and fetch time, crawl delay, next-allowed-fetch time, error counters, the resolved IP and the URL budget used. A content record is keyed by exact hash. It holds the SimHash, the canonical URL and a pointer to the WARC file and offset. Alias records map duplicate URLs to their canonical page. Fetch history is append-only for change estimation. Records are sharded by host or URL hash.

15What security risks does a crawler face, and how do you mitigate SSRF?Very often asked

A crawler fetches attacker-controlled URLs from inside your network, so SSRF is the main risk. Before connecting, I resolve the hostname and block private, loopback, link-local and cloud metadata addresses, such as 10.0.0.0/8, 127.0.0.0/8 and 169.254.169.254. I connect to the validated IP itself, so a DNS rebinding answer cannot swap it, and I re-check every redirect hop. Fetchers run in an isolated network segment with egress-only rules and no credentials. Parsers handle hostile input, so they run sandboxed with memory and time limits. Decompression is capped to stop zip bombs. Only allowed schemes are fetched, usually http and https.

16How do you balance freshness against coverage with a fixed fetch budget?Very often asked

Every fetch either refreshes a known page or discovers a new one, so I split the budget explicitly. For example, a share goes to recrawls ranked by value multiplied by the probability of change, and the rest to discovery ranked by priority. The split is tuned with metrics such as freshness of important pages, the rate of new valuable URLs and the share of 304 or unchanged responses. A high unchanged rate means I am recrawling too much. Hubs such as home pages, category pages and feeds are worth frequent recrawls, because they yield new links. Sitemaps and push signals improve both goals cheaply. Politeness caps still apply per host whatever the split.

17How would you evolve this design for a tenfold increase in crawl volume?Very often asked

First I find which limit binds. Fetching and parsing scale horizontally: add nodes, and consistent hashing moves about 1/N of the hosts. The frontier and URL store need more shards, and per-node memory for Bloom filters must be re-planned for the new URL count. DNS caching capacity and egress bandwidth grow linearly, and their cost often dominates. Politeness does not scale with hardware, so tenfold volume must come from more hosts, or from fewer wasted fetches through better recrawl prediction, conditional GETs and sitemaps. Storage grows linearly, so compression, dedup and revisit records matter more. Parser and rendering tiers scale separately. Multi-region fetching places fetchers near hosts to cut latency.

18How do conditional GETs reduce cost, and what if a server ignores them?Often asked

For each URL I store the ETag and Last-Modified values from the previous response. On a recrawl, I send If-None-Match with the ETag, or If-Modified-Since with the date. An unchanged resource returns 304 Not Modified with no body. That saves bandwidth for both sides, skips parsing and storage, and still counts as a successful fetch for change-rate estimates. Many servers ignore these headers or generate a new ETag on every request. In that case I fall back to my own exact content hash. If the hash matches the last fetch, I record the page as unchanged, possibly as a WARC revisit record. The scheduler learns that the page is stable, even though the server never sent a 304.

19How should the crawler treat rel=canonical tags?Often asked

I treat canonical as a strong hint, not a command, because site owners often get it wrong. Common errors are canonicals pointing to the home page, to a 404 or across unrelated domains. When a page declares a canonical, I record the fetched URL as an alias of the canonical URL. I enqueue the canonical URL if it has not been seen. I lower the priority for recrawling the alias. I trust it more when the canonical and alias content are near-duplicates by SimHash and the same site controls both. If the canonical is broken, I ignore it and keep the fetched URL as its own canonical. Canonical signals, redirects and duplicate clusters together decide which URL represents the page.

20Why back the Bloom filter with a key-value store, and how would you shard it?Often asked

The Bloom filter is a fast, in-memory, probabilistic filter. It cannot be listed, it has false positives and a standard one cannot delete entries. The key-value store keeps the authoritative per-URL record: canonical URL, status, last fetch time, ETag, content hash and change statistics. The recrawl scheduler needs that record anyway. The flow is simple. If the Bloom filter says the URL is absent, it is definitely new, so I insert it. If the filter says present, I can check the store when the URL looks valuable. I shard both by a hash of the normalized URL, or by host, to match frontier ownership and keep checks local. Writes are batched. If a node loses its filter, it can be rebuilt from the store.

21How do you handle DNS resolution at crawl scale?Often asked

DNS is a classic bottleneck. Blocking system resolvers serialize lookups, and public resolvers will rate-limit a crawler. I run local caching resolvers on each crawler node or cluster. Lookups use an async resolver library and respect record TTLs, within a minimum and maximum bound. Hostnames can be prefetched when URLs enter a host's back queue, so the address is ready by the time the gate releases the URL. Negative results such as NXDOMAIN are cached for a shorter time. Resolution failures count toward host health. The resolved IP also matters for politeness, because many hostnames can share one server. Security checks against private address ranges run on the resolved address.

22Many hostnames can sit on one IP address. How does that affect politeness?Often asked

Shared hosting and CDNs mean thousands of hostnames may resolve to one server. Per-host delays alone could still overload that machine. So I add a second limiter keyed by IP address or IP prefix, which caps concurrent connections and request rate to that address. A URL is released only when both its host gate and its IP gate allow it. CDNs complicate this, because one IP fronts huge capacity and is not one fragile server. So IP limits for known large CDN ranges can be looser, and they still adapt to 429 and 5xx responses. The resolved IP can change over time, so the mapping is refreshed with DNS TTLs.

23How would you handle pages that need JavaScript to render their content or links?Often asked

Rendering with a headless browser costs far more than a plain HTTP fetch in CPU, memory and latency. It also fetches many sub-resources, which affects politeness. So I make it a separate, selective tier. The normal pipeline fetches the raw HTML first. Heuristics or learned signals pick pages for rendering, for example a near-empty body, a known single-page-app framework or high value. The renderer runs in sandboxed pools with strict timeouts. It caches shared scripts and stylesheets, and it counts sub-resource requests against the host's politeness budget. Links found after rendering go through the same normalization, trap rules and seen-check pipeline. Most of the web can still be crawled without rendering.

24What privacy and compliance concerns apply to storing crawled pages?Often asked

Public pages can still contain personal data. In India the Digital Personal Data Protection Act, 2023 applies, and other regions have their own laws. I minimize what is kept and why. The crawler fetches only public pages, without logging in or bypassing paywalls, and respects robots.txt plus robots meta and X-Robots-Tag directives. The user-agent string identifies the crawler and links to a contact page. There must be a takedown and removal process that deletes or suppresses content and stops future crawling. Access to raw WARC archives is restricted and audited. Retention is defined, and data is encrypted at rest. Legal review covers copyright use and the purpose of the crawl.

25Why store pages as WARC records, and which record types matter?Often asked

WARC is the ISO 28500 standard archive format used by the Internet Archive and Common Crawl. It stores the full HTTP request and response, with headers and timestamps, so you can reprocess, replay and audit later. Many gzip-compressed records are appended into large files, which suits object storage. Each record compresses on its own, so a reader can seek to a byte offset without unpacking the whole file. The main record types are warcinfo, request, response, metadata and revisit. A revisit record notes that the content matches an earlier capture, so duplicates do not store the payload again. A separate index maps URL and timestamp to file and offset.

26How should the crawler handle redirects?Often asked

I treat a redirect target as a new URL, not something fetched inline. It goes through normalization, trap rules, the seen-check and politeness for its own host. That stops redirects from bypassing rate limits or robots.txt on another domain. I cap redirect chains, at around five to ten hops, and detect loops. Permanent redirects (301, 308) update the source URL's record to point at the target and lower the recrawl priority of the source. Temporary ones (302, 307) keep the original as the canonical URL to recrawl. Each hop is re-checked for SSRF. Redirects to login pages or soft-error pages are marked so they do not pollute the index.

27How would you crawl a huge, important site quickly while staying polite?Often asked

The per-host limit sets the ceiling, so speed comes from using that limit well, not from exceeding it. I follow the site's robots.txt and any published crawl guidance. I reuse keep-alive or HTTP/2 connections so each request costs the server less. Conditional GETs keep recrawls cheap. Sitemaps help target new and changed URLs instead of rediscovering them through links. Many large sites offer database dumps or APIs, Wikipedia's dumps for example, which are better than crawling. Concurrency rises only while response times and error rates stay healthy, and backs off on 429 or 5xx. For partners, a negotiated rate or a push feed is the right approach.

28What metrics and alerts would you put on a production crawler?Often asked

Throughput: fetches per second by status class, bytes downloaded and pages stored. Politeness: requests per host and per IP against limits, 429 and 5xx rates per host, and robots.txt fetch failures. Frontier health: queue depth by priority, age of the oldest due URL, host queue counts and the fraction of fetchers idle while waiting on politeness. Quality: duplicate rate, trap-rule hits per host, the Bloom filter fill ratio and the share of unchanged recrawls. Latency: DNS, connect, time to first byte and parse time. I alert on sudden spikes in errors from one host, URL counts per host growing out of bounds, stalled queues and storage write failures. I also keep a contact channel for webmaster complaints.

29How do you protect fetchers from malicious or broken servers?Often asked

Every fetch has hard limits. There is a connect timeout and a total timeout, so a slow-drip server cannot hold a connection open. The body size is capped, and decompressed output is limited so zip bombs fail fast. There is a maximum header size and a redirect limit. Only expected content types are parsed, and others are dropped or stored as metadata only. Infinite streaming responses hit the size or time cap. Parsers run sandboxed with memory limits, because malformed HTML or PDFs can crash them. Hosts that repeatedly trigger these limits get longer delays or are blocklisted. Async I/O means one bad host ties up only its own connection, not a whole thread pool.

30Does the URL-seen set need strong consistency across shards?Often asked

No. Eventual consistency is fine, which is a big part of why the system scales. If two parsers discover the same new URL at the same moment and both pass the check, the worst case is a duplicate fetch. Dedup and idempotent storage absorb it. Sharding by URL hash routes each URL to one owner, which serializes checks per key and makes races rare. Batched, asynchronous inserts are acceptable. What must be durable is the authoritative URL record and the frontier, so a crash does not cause a full re-crawl. Politeness state needs stronger guarantees, and host-based ownership gives that locally, without global coordination.

31How do you efficiently find stored SimHash fingerprints within a small Hamming distance of a new one?Sometimes asked

A linear scan across billions of fingerprints is impossible. The standard approach, from Manku and colleagues at Google, uses permuted tables. For 64-bit fingerprints with a threshold of 3, split the bits into blocks. By the pigeonhole principle, any match within distance 3 must exactly equal the query on some blocks. Build several tables, each sorted by a different permutation that puts some blocks first. For a query, look up each table on those leading bits, then check the full Hamming distance on the small candidate set. More tables mean fewer candidates but more storage. The tables can be sharded by prefix and queried in parallel.

32How do sitemaps and push protocols fit into discovery and recrawling?Sometimes asked

Sitemaps list a site's URLs, optionally with lastmod. A sitemap file may hold up to 50,000 URLs and 50 MB uncompressed, and index files point to more sitemaps. They help discovery, especially for deep pages with few links. Fresh lastmod values can trigger early recrawls, but I weight them by how accurate each site's lastmod has been historically. Robots.txt can declare sitemap locations. Push protocols such as IndexNow let sites notify participating search engines when URLs change, which cuts wasted recrawls. All of these are hints. URLs from them still go through normalization, the seen-check, trap rules, politeness and robots.txt checks.

33What are soft 404s and how would you detect them?Sometimes asked

A soft 404 is an error or empty page served with a 200 status, for example 'product not found' with a normal template. Storing them wastes space, and recrawling them wastes budget. Detection signals include very short main content, typical error phrases and many different URLs on one host sharing a near-identical SimHash. A strong check is to fetch a deliberately random, non-existent URL on the host and compare its fingerprint to the suspect page. If they match, the page is a soft 404. Detected pages are marked as errors, kept out of the content store and recrawled rarely. Hosts that send many of them get lower budgets.

Objective questions 33

1A conditional GET with If-None-Match returns an unchanged resource. What status code should the server send?Asked almost every time
  1. A304 Not ModifiedCorrect answer
  2. B412 Precondition Failed
  3. C200 OK
  4. D204 No Content

Why: 304 Not Modified tells the client its cached version is still valid, and the response carries no body.

2In a Mercator-style frontier, what are back queues usually keyed by?Asked almost every time
  1. ADiscovery time
  2. BPage priority score
  3. CHost, so each queue holds URLs for a single hostCorrect answer
  4. DContent type

Why: Back queues map to hosts so the crawler can enforce one request at a time and a delay per host.

3Which kind of error can a standard Bloom filter never produce?Asked almost every time
  1. AFalse positives
  2. BHash collisions
  3. CSaturation as it fills up
  4. DFalse negativesCorrect answer

Why: If an item was inserted, all its bits are set, so a Bloom filter never reports an inserted item as absent.

4About how many fetches per second does crawling one billion pages in 30 days need?Asked almost every time
  1. AAbout 3,850
  2. BAbout 38,500
  3. CAbout 385Correct answer
  4. DAbout 39

Why: One billion divided by about 2.59 million seconds is roughly 385 per second on average.

5Under RFC 9309, what should a crawler do if fetching robots.txt returns a 5xx server error?Very often asked
  1. AAssume the site is fully disallowed until robots.txt can be fetchedCorrect answer
  2. BCrawl only the home page
  3. CIgnore the error and use a robots.txt from another host
  4. DCrawl the whole site as if no robots.txt exists

Why: RFC 9309 treats server errors as unreachable and says the crawler must assume complete disallow. A 4xx, by contrast, lets the crawler proceed as if no rules exist.

6A Bloom filter used as the URL-seen set says a URL is present. What does that mean?Very often asked
  1. AThe filter is full and must be rebuilt
  2. BThe URL has definitely been crawled
  3. CThe URL has definitely not been crawled
  4. DThe URL was probably seen, with a small false-positive chanceCorrect answer

Why: Bloom filters have no false negatives but can have false positives, so a hit means 'probably seen'. A miss means the URL is certainly new.

7Under RFC 9309, what may a crawler do if robots.txt returns 404?Very often asked
  1. AStop crawling the host for 30 days
  2. BCrawl any resource on the hostCorrect answer
  3. CAssume complete disallow
  4. DRetry every minute until it succeeds

Why: A 4xx status means robots.txt is unavailable, and RFC 9309 lets crawlers access any resource.

8Per RFC 9309, how long should a crawler normally use a cached robots.txt?Very often asked
  1. AUntil the server sends a 304
  2. BForever, until a 4xx is returned
  3. CNo more than 24 hours, unless the file is unreachableCorrect answer
  4. DUp to 7 days

Why: The RFC says crawlers should not use a cached robots.txt for more than 24 hours, except when the file is unreachable.

9Which response header should a crawler honour on a 429 Too Many Requests?Very often asked
  1. ARetry-AfterCorrect answer
  2. BCache-Control
  3. CETag
  4. DVary

Why: Retry-After tells the client how long to wait before sending more requests.

10Which normalization is generally safe for every URL?Very often asked
  1. ARemoving a trailing slash
  2. BLowercasing the path
  3. CRemoving all query parameters
  4. DLowercasing the hostCorrect answer

Why: Hostnames are case-insensitive, but paths and queries can be case-sensitive or carry meaning.

11What is the main benefit of assigning hosts to crawler nodes with consistent hashing?Very often asked
  1. AIt encrypts traffic between nodes
  2. BIt removes the need for robots.txt
  3. CIt ensures pages are fetched in priority order
  4. DEach host's politeness state lives on one node, and a membership change moves only about 1/N of hostsCorrect answer

Why: Single ownership lets politeness be enforced locally, and consistent hashing limits reshuffling when nodes change.

12A crawled page links to http://169.254.169.254/latest/meta-data/. What should the crawler do?Very often asked
  1. AFetch it over HTTPS instead
  2. BFetch it like any other URL
  3. CBlock it, because it is a link-local cloud metadata address and an SSRF targetCorrect answer
  4. DFetch it only if robots.txt allows it

Why: Metadata endpoints can leak credentials, so crawlers must block private and link-local addresses.

13Which of these is a classic crawler trap?Very often asked
  1. AA robots.txt file with many rules
  2. BA sitemap index file
  3. CA calendar page with endless 'next month' linksCorrect answer
  4. DA 301 redirect from http to https

Why: Dynamically generated calendars can produce an unlimited number of unique URLs.

14A fetcher crashes after leasing URLs but before committing results. What does a lease-based frontier deliver?Very often asked
  1. AExactly-once fetching with no duplicates
  2. BPermanent removal of those URLs
  3. CAt-least-once fetching, because expired leases make the URLs available againCorrect answer
  4. DAt-most-once fetching, so those URLs are lost

Why: Leases expire and the URLs return to the queue, and idempotent writes plus dedup absorb repeat fetches.

15Why is SimHash preferred over an MD5 hash of the page for near-duplicate detection?Often asked
  1. ASimHash is cryptographically stronger
  2. BSimilar documents produce fingerprints with small Hamming distanceCorrect answer
  3. CSimHash output is shorter so it uses less disk
  4. DMD5 cannot hash HTML

Why: SimHash is locality-sensitive, so pages that differ by small edits get fingerprints differing in few bits. MD5 changes completely with a one-byte change, so it only catches exact duplicates.

16What is the minimum robots.txt size that RFC 9309 requires crawlers to parse?Often asked
  1. A10 MiB
  2. B64 KiB
  3. C500 KiBCorrect answer
  4. D1 MiB

Why: Crawlers must parse at least 500 KiB of a robots.txt file.

17robots.txt has 'Disallow: /' and 'Allow: /public'. Is /public/page.html allowed?Often asked
  1. ANo, because Disallow always wins
  2. BNo, because the first rule in the file wins
  3. CYes, because the longest matching rule winsCorrect answer
  4. DOnly if Crawl-delay is set

Why: RFC 9309 uses the most specific (longest) match, and /public is longer than /.

18Which robots.txt directive is not defined in RFC 9309?Often asked
  1. ADisallow
  2. BCrawl-delayCorrect answer
  3. CUser-agent
  4. DAllow

Why: Crawl-delay is a widely used extension, but RFC 9309 does not define it.

19Why can't you delete a URL from a standard Bloom filter?Often asked
  1. ABloom filters are read-only after creation
  2. BClearing its bits could also clear bits shared by other URLs and create false negativesCorrect answer
  3. CDeletion needs a full rehash
  4. DThe hash functions are not reversible

Why: Bits are shared between items, so deletions need a variant such as a counting Bloom filter.

20For a Bloom filter with m bits and n items, which number of hash functions k minimizes false positives?Often asked
  1. Ak = n/m
  2. Bk = m·n
  3. Ck = (m/n)·ln 2Correct answer
  4. Dk = log2(n)

Why: The optimal k is (m/n)·ln 2, which leaves about half of the bits set.

21In Google's large-scale near-duplicate work using 64-bit SimHash, what Hamming distance threshold was used?Often asked
  1. A3Correct answer
  2. B16
  3. C32
  4. D0

Why: Manku and colleagues found that k = 3 on 64-bit fingerprints worked well for billions of pages.

22Cho and Garcia-Molina studied how to allocate a fixed recrawl budget. Which finding is correct?Often asked
  1. AUniform revisit allocation can beat proportional allocation on average freshnessCorrect answer
  2. BPages should be recrawled at random
  3. CRecrawl frequency does not affect freshness
  4. DProportional revisits (more often for faster-changing pages) always maximize average freshness

Why: Their analysis showed that over-investing in pages that change very often hurts average freshness.

23Which WARC record type records that a capture's content is identical to an earlier one, without storing the payload again?Often asked
  1. Ametadata
  2. Bwarcinfo
  3. Cresponse
  4. DrevisitCorrect answer

Why: Revisit records point to an earlier capture so duplicate payloads are not stored twice.

24Why does the crawler drop URL fragments (#section)?Often asked
  1. ARFC 9309 requires it
  2. BFragments break DNS resolution
  3. CThe fragment is not sent to the server, so it does not change the fetched resourceCorrect answer
  4. DFragments are always tracking parameters

Why: Fragments are handled on the client side, so URLs that differ only by fragment fetch the same resource.

25How do you defend the fetcher against DNS rebinding?Often asked
  1. AUse only public DNS resolvers
  2. BDisable DNS caching
  3. CResolve the name once, validate the IP, and connect to that exact IPCorrect answer
  4. DResolve the name twice and compare the answers

Why: Connecting to the validated IP stops a second lookup from returning an internal address.

26How should a crawler treat rel=canonical?Often asked
  1. AAs a binding directive that must always be followed
  2. BAs something to ignore
  3. CAs a hint to weigh against redirects and content similarityCorrect answer
  4. DAs equivalent to a robots.txt Disallow

Why: Canonical tags are often wrong, so they are treated as strong hints and cross-checked.

27Which duplicates does an exact content hash (such as SHA-256) catch?Often asked
  1. AOnly byte-identical contentCorrect answer
  2. BPages with the same topic
  3. CPages that differ only in ads or timestamps
  4. DPages with the same title

Why: Changing even one byte changes the exact hash, so near-duplicates need SimHash.

28What is the main purpose of a per-host URL budget?Often asked
  1. ATo speed up DNS lookups
  2. BTo enforce robots.txt rules
  3. CTo cap how many URLs one host can add, limiting traps and crowd-outCorrect answer
  4. DTo compress WARC files

Why: Budgets stop one host or a generated URL space from eating the crawl.

29Which response header supplies the value that If-None-Match sends?Often asked
  1. ALast-Modified
  2. BContent-Length
  3. CExpires
  4. DETagCorrect answer

Why: If-None-Match carries the ETag from the earlier response, and If-Modified-Since uses Last-Modified.

30Which data structure efficiently finds the host with the earliest next-allowed-fetch time?Often asked
  1. AA Bloom filter
  2. BA hash map keyed by URL
  3. CA FIFO queue of hosts
  4. DA min-heap keyed by next-allowed-fetch timeCorrect answer

Why: A min-heap returns the host that becomes eligible soonest in O(log n) per operation.

31What probabilistic model is commonly used to estimate how often a page changes?Often asked
  1. AZipf distribution over hosts
  2. BGaussian process over page size
  3. CMarkov chain over links
  4. DPoisson process with a per-page change rateCorrect answer

Why: Page changes are typically modelled as a Poisson process, with λ estimated from fetch history.

32What are the per-file limits for an XML sitemap?Sometimes asked
  1. A50,000 URLs or 50 MB uncompressedCorrect answer
  2. B10,000 URLs or 10 MB
  3. C100,000 URLs or 100 MB
  4. D1,000 URLs or 1 MB

Why: The sitemaps protocol caps each file at 50,000 URLs and 50 MB uncompressed.

33A page is disallowed in robots.txt and also has a noindex meta tag. What happens?Sometimes asked
  1. AThe crawler reads noindex first, then obeys Disallow
  2. BThe crawler never fetches the page, so it never sees the noindex tagCorrect answer
  3. Cnoindex overrides Disallow
  4. DBoth are ignored

Why: Robots.txt blocks the fetch, so on-page directives such as noindex are never read.

Track your progress through every blueprint in your dashboard.

Start learning