Torrent / BitTorrent DHT corpus search & crawl statistics
Pricing
from $1.00 / 1,000 results
Torrent / BitTorrent DHT corpus search & crawl statistics
Search a live BitTorrent DHT metadata corpus and see how fast it is growing. Two endpoints: /search with category filters and relevance ranking, and /stats with a per-minute capture rate you can verify. No endpoint or key needed — the corpus is crawled and hosted by this Actor's operator.
Pricing
from $1.00 / 1,000 results
Rating
0.0
(0)
Developer
Raul Sota
Maintained by CommunityActor stats
0
Bookmarked
3
Total users
3
Monthly active users
6 days ago
Last modified
Categories
Share
fast-tracker — BitTorrent DHT corpus search & live crawl statistics
Search a BitTorrent DHT metadata corpus that is being collected right now, and see for yourself how fast it is growing.
You need nothing but a query. No endpoint, no key, no infrastructure — the corpus is crawled and hosted by this Actor's operator.
/search | full-text search across the corpus, with category filters and four orderings |
/stats | how fast the corpus is actually growing, measured so you can check it |
Two ways to use it
Run it. Pick an action, fill in a query, get an Apify dataset. Export to JSON, CSV or Excel like any other Actor.
Call it. The Actor also runs as an HTTP service, so you can query it from your own code with your Apify token:
curl -H "Authorization: Bearer $APIFY_TOKEN" \"https://OPERATOR--fast-tracker.apify.actor/search?q=ubuntu&category=software&sort=relevance&limit=10"curl -H "Authorization: Bearer $APIFY_TOKEN" \"https://OPERATOR--fast-tracker.apify.actor/stats?window_minutes=30"
Both hit the same corpus and return the same records.
/search
| Parameter | Values |
|---|---|
q | free text, ≤200 chars. Separators are normalised, so ubuntu 24 04 matches ubuntu-24.04-desktop-amd64.iso |
category | video audio software archive document image — see the note below |
sort | seeders (default) newest relevance size |
year resolution | e.g. 2024, 1080p |
min_seeders | integer; falls back to the DHT peer count where the tracker scrape has not run |
limit offset | 1–200 (default 50), 0–100000 |
Each record carries infohash, name, size_bytes, files, category,
seeders, leechers, dht_peers, first_seen, magnet, and — where the
parser has reached them — year, resolution, codec, season, episode.
Categories describe file content, not intent
Worth reading before you use the filter, because it is exact and a wrong guess returns nothing rather than less:
| category | what lands there |
|---|---|
archive | .iso .zip .rar .7z .tar .gz — including Linux and game disc images |
software | .exe .msi .dmg .apk .deb .rpm .bin — installers and packages |
video | .mp4 .mkv .avi .mov … |
audio | .mp3 .flac .wav … |
document | .pdf .epub .mobi .doc … |
image | .jpg .png .gif … |
A record is filed by whichever category holds the most bytes, so a release
with a large video file and a small readme is video.
The one that catches people: searching ubuntu under software returns
nothing, because the ISO is an archive. Leave the category unset unless you
know which side of that line your target falls on.
This is a crawl, not a catalogue
Worth setting expectations before your first query. The corpus is built by sampling the DHT and fetching metadata for what it finds, so its contents are whatever peers happened to be sharing when the crawler looked. It is not seeded from any site's index and it is not curated.
Practically: broad terms work well, a specific title may genuinely be absent, and an empty result is a real answer rather than an error. Run the Crawl statistics action to see how large the corpus is and what categories it actually holds.
About the orderings
seeders, newest and size are the corpus server's own orderings. The
request is forwarded and its response is returned untouched.
relevance is different, and worth understanding before you rely on it.
The underlying API has no relevance ranking: its full-text index is never asked
to score matches, and its fast index ranks by seeder count fixed at build time.
The three orderings it actually implements are seeders, size and capture time.
So relevance is computed by this Actor. It pulls a candidate window in the API's own best-first order and re-ranks it on a transparent score — how much of your query the name contains (0.60), whether those words appear together and in order (0.20), how early the match starts (0.10), how much of the name is the match so packs sink (0.05), and seeders as a tiebreak only (0.05).
That means relevance re-ranks candidates, not the whole corpus. A record
this score would love, sitting outside the candidate window, will not appear.
The X-Relevance-Candidates and X-Relevance-Exhaustive response headers tell
you which situation you are in. Ranking changes the order of records and
nothing else — no injected score field, no annotation.
/stats — meant to be checked, not believed
Any dataset can claim to be fresh. The claim is only worth something if you can arrive at the number yourself, so nothing in this report is taken from server-side reporting. Two independent measurements:
1. Count the records. Walk the search API backwards through capture time
and bucket every record into whole UTC minutes by its first_seen field. The
rate is the count divided by the window — and the report ships the count, the
window, the pages fetched and the records examined, so you can check the
division rather than trust it.
2. Watch the counter move. Read the corpus row count before the walk and again after it. If the corpus were a static dump, or the rate a stored constant, that delta would be zero while the histogram claimed otherwise.
The two agreeing is the actual claim. Either alone is a number in a JSON file.
Three details decide whether the figure is honest, and each is a named behaviour rather than a footnote:
- The minute in progress is excluded. Counting a partial minute as a whole one biases every rate downwards, by a random amount depending on when the run started.
- Records are deduplicated by infohash. The corpus is being written to while it is read; offset paging re-serves rows when new records land ahead of the cursor.
- A truncated walk shortens the window instead of extrapolating. If the page
budget runs out, the half-counted minute is dropped from both the count and
the divisor, and the result says
complete: false.
Sample output
{"type": "fast-tracker-crawl-report","generated_at": "2026-08-07T04:15:00.412Z","instance_id": "4824992f720bacee","corpus": {"torrents": 213727,"searchable": 213727,"tracker_scraped": 201668,"tracker_scraped_pct": 94.4,"newest_capture": "2026-08-07 04:14:59","newest_capture_age_seconds": 31,"by_category": { "video": 138603, "audio": 41205, "software": 18844 }},"capture_rate": {"window_start": "2026-08-07T03:15:00.000Z","window_end": "2026-08-07T04:15:00.000Z","window_minutes": 60,"captured": 8855,"per_minute": 147.6,"per_hour": 8856,"per_day_projected": 212544,"complete": true,"per_minute_series": [{ "minute": "2026-08-07T03:15Z", "captured": 149 },{ "minute": "2026-08-07T03:16Z", "captured": 143 }// ... one entry per minute in the window, zeroes included],"method": {"derivation": "every returned record bucketed by first_seen into whole UTC minutes; captured / window_minutes","excludes_minute_in_progress": true,"deduplicated_by": "infohash"},"accounting": {"pages_fetched": 45, "page_size": 200, "records_examined": 8912,"records_counted": 8855, "duplicates_skipped": 57, "truncated": false}},"cross_check": {"torrents_before": 213727, "torrents_after": 213802,"delta": 75, "elapsed_seconds": 31.2,"per_minute": 144.2, "confidence": "good"}}
Written to the dataset and to the key-value store under CRAWL_STATS and
OUTPUT.
The cross-check needs a measurable interval to mean anything. Under ten seconds the crawler's batch-commit boundaries dominate and the figure is noise, which is what
confidencereports. Set Cross-check dwell to 60 seconds or more if you intend to quote it.
Over HTTP, /stats is computed at most once per cache interval and shared
between concurrent callers. Without that, the endpoint would be an amplifier
pointed at the machine doing the crawling.
What this Actor does not expose
The corpus host is infrastructure, not part of the product, and it stays out of everything this Actor produces.
Never written to a dataset, the key-value store, an HTTP response or a run log: the corpus endpoint's URL, hostname, IP or port; its API key; filesystem paths; software versions; crawler tuning; any peer or DHT address.
- Credentials are not input fields. They live in the operator's environment, so there is no form field a caller can set — which also means there is no way to point this Actor at a host of your choosing and have it fetch that instead.
- The key travels in a header, never a query string.
- Reports identify the source only by
instance_id, a SHA-256 prefix of the origin. Two reports from the same corpus share an id; the id leads nowhere. - Every string reaching a log line, error response or failure message passes a redactor first. Network errors quote the host they failed to reach, and that is the leak that actually happens.
- Corpus statistics are copied field by field from an allow-list, so a future server release cannot start publishing something host-shaped by accident.
The test suite asserts this end to end: after a full run, no file the Actor writes contains the endpoint, its host, or the key.
Limits
| Paging depth | offset is capped at 100000, so about 100200 records are reachable for any one query. Narrow the query rather than paging deeper. |
| Page size | 200 records. |
| Relevance cost | One relevance request becomes several upstream requests — one per 200 candidates. |
| Statistics cost | The rate is counted from real records, so a 60-minute window is roughly 45 requests. Over HTTP the window is capped at 60 minutes and defaults to 10. |
| Freshness | Search responses are cached for 30s upstream. year and resolution are only populated for records the parser has reached. |
Responsible use
This Actor searches an index of public BitTorrent DHT metadata: infohashes, names, sizes and swarm counts. It does not host, transfer or distribute any content, and it does not resolve to any file.
A DHT crawl indexes whatever it finds, which includes material that is illegal to possess in most jurisdictions. The corpus operator is responsible for filtering what their instance collects and serves; if you build on this output, you are responsible for what you do with it. Results are metadata records about swarms that exist, not an endorsement of any of them, and nothing here is a recommendation to download anything.
Background on the collection method and its obligations: fast-tracker and its NOTICE.md.
Not affiliated
with any torrent site, tracker, or index. The corpus is collected directly from the BitTorrent DHT by the operator's own crawler.
MIT licensed.