Design a web crawler
Discover and download billions of pages politely and efficiently: the URL frontier, deduplication and avoiding traps.
On the roadmap:Interview Ready · step 3: Feeds, chat and notifications
Lesson 5 of 11 · 11 min read · quiz · exercise
The problem
A web crawler starts from some known URLs, downloads each page, extracts the links and follows them. Search engines use crawlers to build their index, and others use them for archiving, price tracking or monitoring.
Requirements
- Scale: about a billion pages a month.
- Polite: do not overload sites, follow
robots.txt. - Robust: bad HTML, huge files, slow servers and traps must not break it.
- Extensible: later add new content types (images, PDFs).
- Avoid fetching the same page twice.
Estimates
1 billion pages a month is about 400 pages a second on average. At roughly 500 KB each (HTML plus metadata), that is around 500 TB a month, so storage and network are the big costs.
High-level design
Figure SDA-CSD-05-1 · Crawler pipeline · © forcsguy.com
- The URL frontier hands out URLs to crawl next.
- Fetchers download pages (resolving names with a local DNS cache, since DNS lookups can dominate time).
- The parser validates and processes the HTML.
- A content-seen check drops pages identical to ones already stored.
- Links are extracted, normalised, filtered, and checked against URL-seen before going back to the frontier.
The web as a graph
Figure SDA-CSD-05-2 · Crawling is graph traversal · © forcsguy.com
The URL frontier
The frontier is the brain. It decides what to fetch and when.
- Priority: important or frequently changing pages first. Priority queues ordered by a score (for example link popularity or freshness).
- Politeness: one queue per host, and each host is handled by one worker that waits between requests (for example one request per second to a given site).
Figure SDA-CSD-05-3 · URL frontier: priority and politeness · © forcsguy.com
Because the frontier is huge, keep most of it on disk with an in-memory buffer at the front.
Keeping one polite worker per host
Figure SDA-CSD-05-4 · Politeness queues · © forcsguy.com
Not doing the same work twice
- URL seen: before queueing a link, check it. A Bloom filter (or a hash set partitioned across servers) keeps this small and fast. Normalise URLs first (lowercase host, remove fragments, sort query parameters).
- Content seen: pages often exist under many URLs. Compare a hash of the content, or a similarity fingerprint for near duplicates, and skip repeats.
Staying out of trouble
- robots.txt: fetch and cache it per host, and obey it.
- Spider traps: endless generated URLs. Cap URL length, link depth and pages per host.
- Timeouts and size limits so one slow or giant response cannot stall a worker.
- Dynamic pages: content built by JavaScript needs a rendering step, which is much more expensive.
- Harmful content: filter spam or illegal material before storing or indexing.
More ways to make it fast and robust
- Two-stage frontier. Front queues carry priority (each queue has a score band and is picked with a bias toward the higher bands); back queues carry politeness (one host per queue). A URL passes through both, so you get "important first" and "gentle per site" together.
- Freshness. Recrawl by observed change history, and re-visit important pages more often. Recrawling everything is too costly.
- DNS is a hidden bottleneck. Lookups can take tens to hundreds of milliseconds and many resolver interfaces block a thread, so keep your own DNS cache and refresh it on a schedule.
- Locality and timeouts. Put crawl servers near the sites they fetch from, and give each fetch a short timeout so one slow host cannot stall a worker.
- Robots rules are fetched once and cached, then obeyed before each fetch.
- Resilience. Spread URLs over downloaders with consistent hashing, checkpoint the crawl state so a crash resumes instead of restarts, and validate pages before storing them.
- Extensible by modules. New content types (images, a copyright monitor) plug in after the downloader without redesigning the pipeline.
- Noise. Skip ad blocks, spam and low-value pages with a quality filter; cap URL length and per-site page counts to limit spider traps, and have a person exclude sites that still trap you.
- Beyond search. The same engine serves archiving, mining and brand or copyright monitoring.
Figure SDA-CSD-05-5 · Plugging new modules into the crawler · © forcsguy.com
Figure SDA-CSD-05-6 · Distributing the crawl · © forcsguy.com
Scaling and reliability
- Add many fetcher workers, partitioned by host (consistent hashing keeps assignments stable).
- Make workers stateless and checkpoint the frontier, so a crashed worker's URLs are re-queued.
- Spread crawlers across regions to be closer to the sites being fetched.
- Re-crawl by schedule: pages that change often (news) are revisited more often than static ones.
Worked numbers: why it is about many hosts, not one fast fetcher
Target: 1 billion pages a month, about 400 pages per second, at about 500 KB each.
- Bandwidth: 400 x 500 KB = 200 MB/s, about 1.6 Gbit/s sustained, before retries and robots.txt fetches. Many machines in several places, not one big link.
- Politeness sets the shape. If you allow one request per second per host, then to fetch 400 pages a second you must be talking to at least 400 different hosts at the same moment. A single site with 100,000 pages would take 100,000 seconds, nearly 28 hours, to crawl at that pace. So a crawler is a scheduler that interleaves thousands of hosts, which is exactly what the per-host queues do.
- Seen-URL memory. With 10 billion known URLs, an exact set of 8-byte hashes is 80 GB. A Bloom filter at about 10 bits per URL (1% false positives) needs 12.5 GB, and a false positive only means skipping a page you could have crawled.
- Storage: 1 billion x 500 KB = 500 TB a month raw. Compress and deduplicate, and keep only what you will index.
Figure SDA-CSD-05-7 · Throughput comes from interleaving many hosts · © forcsguy.com
Staying fresh: not every page needs the same schedule
Re-crawling everything monthly wastes effort on pages that never change and misses news that changes hourly. Practical schedules:
- Keep the observed change history per page (did the content hash change since the last visit?). Visit pages that change often more frequently, and stable pages less often, within limits.
- Use hints:
Last-Modified,ETagand conditional requests (If-None-Match) let the server answer "not modified" in a few bytes. - Give importance a vote: popular pages, and pages that many others link to, are revisited sooner.
- Keep a small fast lane for news and feeds, driven by sitemaps and feed updates.
Figure SDA-CSD-05-8 · Recrawl by how often a page changes · © forcsguy.com
Walking through a spider trap
A calendar page links to "next month", which links to the next month, forever. A naive crawler follows it, fetching millions of near-identical pages from one host. Defences, layered: cap URL length and path depth; cap pages per host per period; detect repeating patterns (the same path with only a number changing); skip pages whose content hash you have seen; and let an operator add a rule when a site still traps you. None is perfect, so budgets per host are the safety net.
Mistakes people make
- Ignoring
robots.txtand crawl-delay. It gets you blocked, and it is rude. - Not normalising URLs.
HTTP://Example.com/a?b=1&a=2#topandhttp://example.com/a?a=2&b=1are the same page. Lowercase the host, drop fragments, sort parameters, remove tracking parameters. - One slow host stalling workers. Always use timeouts and size limits.
- Treating the frontier as a plain FIFO. It ignores priority and politeness.
- Fetching JavaScript-built pages as plain HTML. The content may be missing; rendering is a separate, costlier pipeline.
- No deduplication of content. The same article under ten URLs wastes storage and pollutes the index.
Try it yourself
Build the Bloom filter lab and measure its false-positive rate and memory against an exact set, then read the seen filtering lesson. The consistent hash ring lab shows how to assign hosts to crawler workers so assignments stay stable.
Real-world reading
Related reading
- System Design (Karan Pratap Singh)Karan Pratap Singh · karanpratapsinghGitHub
- CAP Twelve Years Later: How the Rules Have ChangedEric Brewer · InfoQBlogs
- Tech Dummies: System Design Case StudiesNarendra L · Tech DummiesYouTube
- Tumblr Architecture - 15 Billion Page Views a Month and Harder to Scale than Twitter - High Scalability -High Scalability engineers · High ScalabilityCase Studies
Show 6 moreShow fewer
- Cloudflare Learning Center: What is a CDN?CloudflareDocumentation
- Scaling Pinterest - From 0 to 10s of Billions of Page Views a Month in Two Years - High Scalability -High Scalability engineers · High ScalabilityCase Studies
- The Site Reliability WorkbookGoogle SRE team · O'Reilly / GoogleBooks
- Performance Optimization on Image, Video, Page LoadGoogle engineers · GoogleCase Studies
- Site Reliability Engineering at Dropbox - Tammy Butow, Site Reliability Engineering Manager at DropboxDropboxYouTube
- The WhatsApp Architecture Facebook Bought For $19 Billion - High Scalability -High Scalability engineers · High ScalabilityCase Studies
Check your understanding
Question 1 of 3
0 correct so far
What is the purpose of politeness in a crawler?
Go deeper
- Mercator: A Scalable, Extensible Web Crawler by Heydon and Najork: a classic design paper; easy to find online
- Dynamic rendering by Google Search Central: why scripts change what a crawler sees
- Web crawling lecture notes by Donald Patterson (UC Irvine): frontier, politeness and priority in a course setting
Practise it: Ingest crawled pages
Everything below is already set up for this lesson: change the design, run the traffic, and see whether you meet the goal.
- 1The task
- 2Build and test
Crawlers write about 1,500 pages per second into storage. Most traffic is writes, and the database cannot apply them at that rate.
Goal: Under 1% errors, queue clears in 30 seconds.
Writes can be buffered, but only as fast as the database can drain them. How can that rate be raised?
Try it yourself
You must crawl 1 billion pages a month. Estimate pages per second and the monthly storage for page content, and say why a single crawler machine is not enough.
Click what a strong design here would need:
More in Design practice
© 2026 forcsguy.com. Original lesson text and diagrams. Books and sites linked above belong to their authors.