All skills
simota avatar

/trawl

@95ba0d9
by shingo imotasimota/agent-skills85 stars
15

Architecting crawl and scraping systems: distributed crawler topology, URL frontier, politeness, compliance. Architecture-only. Not for single-page scraping (Vector) or ETL pipelines (Stream).

Use this Skill: https://skilld.dev/gh/simota/agent-skills/trawl

This session only. Nothing lands on disk.

referencefrontier-design.md

≈1.9k tokens on demand. Your agent reads this file only when SKILL.md points to it.

URL Frontier Design

Frontier Architecture

The URL frontier is the central data structure of a web crawler. It manages URL discovery, deduplication, prioritization, and scheduling.

  Discovered URLs
        │
        ▼
  ┌───────────┐     ┌──────────────┐
  │ URL Canon- │────▶│  Seen-Set    │──── Already seen? → Discard
  │ icalization│     │ (Dedup)      │
  └───────────┘     └──────┬───────┘
                           │ New URL
                           ▼
                    ┌──────────────┐
                    │  Priority    │
                    │  Scoring     │
                    └──────┬───────┘
                           │
                           ▼
                    ┌──────────────┐
                    │  Domain      │
                    │  Queues      │──── One queue per domain
                    └──────┬───────┘     (politeness enforcement)
                           │
                           ▼
                    ┌──────────────┐
                    │  Worker      │
                    │  Assignment  │──── Consistent hash → worker
                    └──────────────┘

Deduplication Strategies

Bloom Filter

Parameters for 10 billion URLs, 1% FPR:
- Size: ~11.5 GB (1.2 bytes/element × 10^10)
- Hash functions: 7 (optimal k = ln(2) × m/n)
- Lookup: O(k) = O(7)
- Insert: O(k) = O(7)
- Deletion: Not supported

Partitioned Bloom filter (for distributed):
- Split by hash(URL) % partition_count
- Each partition: independent Bloom filter
- Merge: bitwise OR (grows FPR — avoid)

Best for: Large/Web-scale tiers, append-only dedup, memory-constrained environments.

Cuckoo Filter

Parameters for 10 billion URLs, 1% FPR:
- Size: ~15 GB (1.5 bytes/element × 10^10)
- Bucket size: 4 entries
- Fingerprint size: 12 bits
- Max kicks: 500
- Deletion: Supported (with false-negative risk at high load)

Advantages over Bloom:
- Supports deletion (domain blocking, URL expiry)
- Better cache locality (single lookup location)
- Similar or better FPR per byte at moderate loads

Best for: Large tier with domain blocking, URL expiry, or dynamic scope changes.

Redis Seen-Set

Implementation:
- SADD url_seen_set <canonical_url>
- SISMEMBER url_seen_set <canonical_url>

Memory (10M URLs, avg 80 bytes/URL):
- ~1.6 GB (with Redis overhead ~2x raw)

Scaling:
- Redis Cluster for >50M URLs
- Sharding by hash(domain) for locality

Best for: Small/Medium tiers, exact dedup, operational simplicity.

RocksDB

Implementation:
- Key: canonical URL (byte string)
- Value: crawl metadata (last_crawl, status, content_hash)
- Lookup: point query O(log N) with bloom filter acceleration
- Storage: LSM tree, compaction amortizes write cost

Memory:
- Block cache: 256 MB-1 GB (configurable)
- Data on disk: ~100 bytes/URL including metadata
- 1 billion URLs ≈ 100 GB on disk

Advantages:
- Exact dedup with metadata
- Disk-backed (RAM-efficient)
- Supports range scans (domain prefix queries)

Best for: Medium/Large tiers, when metadata per URL is needed, disk is cheaper than RAM.

Priority Queue Design

Multi-Level Priority Queue

Level 1 — Seed URLs (manually curated, highest priority)
Level 2 — Sitemap URLs (sitemap.xml priority signal)
Level 3 — In-link count (more inbound links = higher priority)
Level 4 — Depth-based (BFS-first, deeper = lower priority)
Level 5 — Discovery order (FIFO within same priority)

Within each level: domain-level round-robin for politeness

Domain-Level Politeness Queues

Structure:
  Global priority queue
    └── Domain queue: example.com (sorted by URL priority)
    └── Domain queue: other.com (sorted by URL priority)
    └── Domain queue: ...

Drain strategy:
  Round-robin across domain queues
  Per-domain rate: min(token_bucket_rate, 1/crawl_delay)
  Empty domain queues are removed after TTL (1 hour)

Re-Crawl Scheduling Models

Model Logic Best For
Fixed TTL Re-crawl every N days Simple, predictable budget
Change-detection ETag/Last-Modified comparison, skip if unchanged Bandwidth-efficient
Exponential backoff Double interval on each unchanged check (cap at 30 days) Low-change content
Adaptive Estimate change rate from history, schedule proportionally High-value content
Freshness-weighted Combine content value × change rate → priority score Mixed-importance corpus

URL Canonicalization

RFC 3986 Normalization Pipeline

Input: https://WWW.Example.COM:443/path/../page?b=2&a=1#fragment

Step 1 — Lowercase scheme and host:
  https://www.example.com:443/path/../page?b=2&a=1#fragment

Step 2 — Strip default port:
  https://www.example.com/path/../page?b=2&a=1#fragment

Step 3 — Resolve path (remove .., .):
  https://www.example.com/page?b=2&a=1#fragment

Step 4 — Sort query parameters:
  https://www.example.com/page?a=1&b=2#fragment

Step 5 — Drop fragment:
  https://www.example.com/page?a=1&b=2

Step 6 — Strip trailing slash (optional, domain-specific):
  https://www.example.com/page?a=1&b=2

Output: https://www.example.com/page?a=1&b=2

Additional Normalization Rules

Rule Example When to Apply
Strip tracking params Remove utm_*, fbclid, gclid Always for dedup
Decode unreserved chars %7E → ~ Always
Strip session IDs Remove JSESSIONID, PHPSESSID from URL Always
WWW normalization www.example.com = example.com Per-domain config
Protocol normalization http:// → https:// if site redirects Per-domain config

Frontier Persistence

Persistence Strategies by Scale

Scale Strategy RPO RTO
Small Redis RDB snapshots (every 5 min) 5 min < 1 min
Medium Redis AOF (every 1 sec) + RDB 1 sec < 1 min
Large Kafka offsets + RocksDB WAL 0 (committed) < 5 min
Web-scale HDFS checkpoint + HBase WAL 0 (replicated) < 10 min

Recovery Protocol

1. Detect failure (heartbeat timeout or process crash)
2. Load last frontier snapshot
3. Replay WAL/AOF entries since snapshot
4. Mark in-flight URLs as PENDING (not COMPLETE)
5. Reset domain rate limiters
6. Resume crawl from recovered state

Strategy Comparison (SKILL.md excerpt)

URL frontier is the core data structure of any crawler. Select by scale and requirements.

Strategy Memory/10B URLs Deletion FPR Best For
Bloom filter ~1.2 GB No ~1% Large/Web-scale, append-only dedup
Cuckoo filter ~1.5 GB Yes ~1% Large, needs deletion (domain block)
Redis seen-set Exact (high) Yes 0% Small/Medium, exact dedup
RocksDB On-disk (low RAM) Yes 0% Medium/Large, disk-backed exact dedup

Priority queue design: Domain-level politeness queues (one queue per domain, round-robin drain) with priority signals: Sitemap priority, link depth, content freshness estimate, PageRank seed score.

URL canonicalization: RFC 3986 normalization → lowercase scheme/host → strip default port → sort query params → drop fragment → resolve relative paths.

Full frontier patterns → reference/frontier-design.md

Source: SKILL.md on GitHub

2 warnings1mo3 checks · Risk SAFE
  • Gen Agent Trust Hub1mo

    The 'trawl' skill is a comprehensive architecture tool for designing web crawling and scraping systems. It provides deep technical guidance on crawler topology, URL frontier management, and legal compliance without generating any executable code. No security risks or malicious patterns were identified.

  • Socket1mo

    1 alert: gptSecurity

  • Snyk1mo

    Risk: MEDIUM · 1 issue

Signed by skilld at 95ba0d9. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 2 days ago.

Activeupdated last month

README badge

README badge for simota/agent-skills/trawl