Design Web Crawler — System Design Interview Practice
Design a web crawler that can discover and download billions of web pages efficiently. Work through the requirements, architecture trade-offs, and an interactive design review.
Concepts and architecture decisions to consider
- crawlingConcept to explore
- distributed systemsConcept to explore
- web scrapingConcept to explore
- data collectionConcept to explore
Interview prompt
Design a polite, distributed web crawler that discovers and fetches billions of pages, respects robots and host limits, avoids duplicates and traps, and produces replayable crawl data.
- Define URL canonicalization, discovery, fetch, redirect, robots, politeness, content identity, revisit, and durable frontier semantics.
- Partition by host for per-domain concurrency/rate limits, deduplicate globally, and prevent infinite loops, traps, oversized content, and unbounded queues.
- Separate frontier scheduling from fetch workers, parsing, storage, and indexing; make leases, retries, checkpoints, and replay explicit.
- Explain abuse handling, takedown/privacy, TLS failures, poisoned pages, observability, bandwidth cost, and graceful slowdown.
Requirements and scale assumptions
- Seed and discover URLs, canonicalize and prioritize them, fetch politely, parse links/content, store responses, and emit crawl metadata.
- Support robots.txt/HTTP policies, redirects, retries, conditional requests, content hashing, revisit schedules, and host-level dashboards.
- Provide pause/resume, URL/domain exclusion, deletion/takedown, checkpoint recovery, and deterministic replay of frontier decisions.
- Guarantee bounded per-host concurrency and a crawl decision within seconds while preventing unbounded retries or spider traps.
- Scale to billions of pages and millions of hosts without a single hot key or unbounded synchronous work.
- Do not lose committed state; make retries and duplicate events safe.
- Degrade safely when downstream workers, caches, or external dependencies fail.
- 10B pages, 10M hosts, and 1M fetches per second peak
- Partition by the primary tenant, user, item, or geographic key and isolate hot partitions.
- Keep serving state bounded; retain raw events or durable records for replay and auditing.
- Peak scale: 10B pages; 10M hosts; 1M fetches/s — Capacity assumption that drives partitioning and backpressure.
- Latency target: per-host limits; retries bounded — User-facing budget for the primary request or read path.
- Durable boundary: Committed before async — Canonical URL/frontier state and immutable fetch records are authoritative; indexes and dedupe caches are rebuildable.
- Async boundary: At-least-once workers — Keep URL frontier with priority queue, Bloom filter for duplicate detection, Consistent hashing for URL distribution off the synchronous path.
Key entities
- DocumentVersiondocumentId, sourceVersion, contentHash, aclVersion, language, updatedAt
Canonical web crawler content and access-policy version used for indexing.
- IndexGenerationgenerationId, sourceWatermark, schemaVersion, status, alias, createdAt
Rebuildable web crawler index generation that can be validated before an atomic alias swap.
- QuerySessionqueryId, tenantId, normalizedQuery, filters, generationId, nextCursor
Auditable web crawler query context with filters, cursor, and the generation used to answer it.
- RankingFeedbackqueryId, documentId, position, action, modelVersion, occurredAt
Privacy-scoped web crawler relevance signal for offline evaluation and ranking improvement.
Data flow
- 1. Accept and authorize source changesThe web crawler ingestion boundary validates content, tenant ownership, ACLs, versions, and idempotency before publishing a document change.
- 2. Retrieve and rank candidatesThe query service applies authorization filters, retrieves from the active web crawler generation, ranks within the latency budget, and returns generation freshness.
- 3. Build a safe index generationPartitioned workers transform web crawler documents, checkpoint progress, validate counts and ACL parity, then atomically swap the serving alias.
- 4. Handle freshness and deletesTombstones and ACL changes propagate through the same pipeline so deleted or newly restricted web crawler content is not left searchable.
- 5. Measure relevance and recoverFeedback, query traces, lag, and failed partitions drive web crawler ranking evaluation, replay, and bounded degraded behavior.
Deep dives and trade-offs
- ACL correctness and index generationsFilter web crawler results by tenant and effective ACL, or prove the active generation contains the same policy snapshot. Build shadow generations and swap aliases atomically so partial reindexes are never visible. Keep source versions and ACL snapshots for replay when permissions or content change.
- Latency, cursors, and graceful degradationUse bounded candidate retrieval, stable sort keys, and generation-aware cursors for web crawler pagination. Serve the last healthy generation when a new build is incomplete, but expose freshness and avoid silently violating authorization. Protect the query path with timeouts, circuit breakers, and per-tenant quotas.
- Relevance feedback without leakageSeparate web crawler click or conversion signals from personally identifying data and honor retention or deletion requests. Evaluate ranking by query class and tail latency, not only aggregate click-through. Use replayable query sets and staged model or synonym changes before production rollout.
- Synchronous indexing versus queued indexingCommit the source version synchronously and index asynchronously with a visible freshness contract. Waiting for index mutation makes writes fragile and cannot guarantee immediate consistency at scale.
- Denormalized ACL fields versus filter-time checksDenormalize safe, versioned authorization facts when it meets the policy model, while retaining a source-of-truth check for sensitive results. Stale permissions can become a data-leak path if index updates are treated as authoritative.
- Lexical, vector, or hybrid retrievalStart with the retrieval method that matches the corpus and latency budget, then add hybrid ranking behind an experiment and rollback boundary. Adding embeddings without freshness, explainability, or access-control design increases cost without improving user trust.