# aquatic is a BitTorrent tracker written in Rust, one crate per protocol

> aquatic is a high performance open BitTorrent tracker whose UDP, HTTP and WebTorrent implementations are separate Rust crates in one Cargo workspace, with everything held in memory, Prometheus metrics and per protocol load testers. It is aimed at operators who want a tracker they can put behind a real network, and it ships as source rather than as a service.

**greatest-ape/aquatic** — High-performance open BitTorrent tracker (UDP, HTTP, WebTorrent)

- Repository: https://github.com/greatest-ape/aquatic
- Stars: 628 · Forks: 48
- Language: Rust
- License: Apache-2.0
- Published: 2026-10-22 · Updated: 2026-10-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/greatest-ape-aquatic

## One tracker, three protocol implementations

aquatic is described as a high performance open BitTorrent tracker, consisting of sub-implementations for different protocols, and the protocol table is the first thing to read because it also carries the platform requirements. The UDP implementation speaks BitTorrent over UDP and needs a Unix-like system, the HTTP implementation speaks BitTorrent over HTTP optionally over TLS and needs Linux 5.8 or later, and the WebTorrent implementation speaks WebTorrent optionally over TLS and needs Linux 5.8 or later. That last detail is the one that catches people out, since a tracker that looks portable is not. The name of the project carries a small joke, since the tracker is called aquatic because it thrives under a torrent of bits. The features at a glance are a multithreaded design for handling large amounts of traffic, all data stored in memory with no database needed, IPv4 and IPv6 support, support for forbidding and allowing info hashes, Prometheus metrics, automated CI testing of full file transfers, and optional periodic exports of full scrape statistics for the UDP implementation only. The audience is the operator of a tracker, and the two known users named in the README are the explodie.org public tracker and webtorrent.dev.

## Why the UDP path is the one with a load test chart

The README gives the UDP implementation a dedicated performance section with a throughput image and a link to more benchmark details in the documents directory, and the reason is not vanity. A public BitTorrent tracker is a UDP service by tradition, because the UDP tracker protocol is what clients query when they announce, and the volume of that traffic is what determines whether a tracker is usable. The known user list quantifies it: the explodie.org public tracker typically serves around 100,000 requests per second. A number like that changes what an implementation needs. The design answers it in the feature list rather than in a single optimisation, with multithreading for handling large amounts of traffic and in-memory storage so that a request does not wait on a database. The UDP implementation also carries one feature the others do not, the optional periodic exports of full scrape statistics, and the project as a whole adds automated CI testing of full file transfers, the kind of check that catches regressions in a service where a subtle protocol bug is invisible until a swarm breaks. For an operator, the practical question is whether the benchmark on your own hardware and your own network matches what the author measured, and the load test applications are the way to find out.

## The workspace layout, and what each crate is for

The Cargo.toml defines a single workspace with resolver 2 and a version of 0.9.0 shared across the package, and the member list is the clearest map of what the project contains.

```toml
members = [ 
    "crates/bencher",
    "crates/combined_binary",
    "crates/common",
    "crates/http",
    "crates/http_load_test",
    "crates/http_protocol",
    "crates/peer_id",
    "crates/toml_config",
    "crates/toml_config_derive",
    "crates/udp",
    "crates/udp_load_test",
    "crates/udp_protocol",
    "crates/ws",
    "crates/ws_load_test",
    "crates/ws_protocol",
]
```

The pattern is consistent across the three protocols. There is a server crate, a load test crate and a protocol crate for each of UDP, HTTP and WebTorrent, which means the client to tracker wire format is separated from both the server and the benchmarking harness. crates/common holds what the implementations share, crates/peer_id extracts BitTorrent client information from peer identifiers, and crates/toml_config with its derive crate is the configuration layer. The release profile is tuned for throughput, with thin link time optimisation and opt-level 3, and the test and bench profiles inherit a release-debug variant with debug information on, which is what you want when a benchmark run needs to be profiled rather than just timed.

## Load testing and the client to tracker protocol crates

The auxiliary software section of the README is the part that makes this usable by someone who is not the author. There are load test applications for each protocol, aquatic_udp_load_test, aquatic_http_load_test and aquatic_ws_load_test, described as useful for profiling, plus aquatic_bencher for automated benchmarking of aquatic and other trackers. There are also libraries for client to tracker communication, aquatic_udp_protocol, aquatic_http_protocol and aquatic_ws_protocol, which are usable on their own if you are writing a client rather than running a server. The peer identifier crate is the odd one out and the most reusable, since extracting client information from peer identifiers is something any tool that inspects a swarm needs. The presence of the bencher crate is worth noticing for a different reason. A tracker that a real community depends on is an operational responsibility, and the ability to run the same benchmark against your own tracker and against others is what turns a claim about throughput into a measurement. The repository also carries a docker/ directory, a scripts/ directory, a documents/ directory holding the benchmark details, a TODO.md, a deny.toml for dependency licence checking, and a CHANGELOG.md.

## In-memory state, and what that rules out

The design decision with the widest consequences is that all data is stored in memory with no database needed. For a tracker, the state is small and per torrent, the announce interval for a peer, the swarm membership for a given info hash, the counters for the scrape endpoints, and the set of banned hashes. Holding that in memory is what makes a high request rate achievable without a database in the request path, and it is the reason the project can claim a multithreaded design that handles large amounts of traffic. It also means the state is gone when the process stops, which for a tracker is usually acceptable because the peers reannounce and the swarm rebuilds itself, but it is a real constraint for anyone who expects a tracker to remember history. Combined with the supporting features, the scope becomes clear. There is support for forbidding and allowing info hashes, which is how a tracker operator bans a torrent, and it is worth being clear that this is an in-memory list, so the bans do not survive a restart unless you reconfigure them. For an operator whose policy is expressed as a long list of banned hashes that others contribute, that is a decision to make deliberately rather than discover at a restart.

## How it compares to a tracker you install and forget

The realistic alternatives fall into two groups. The first is the mainstream BitTorrent tracker software, the kind of tracker server that has been the default choice for years, which typically stores its state in a database and ships as a single binary with a web interface. The difference in approach is that such a server is built around a persistent store, which makes it easy to keep history and to survive restarts, at the cost of putting a database in the path of every announce. aquatic inverts that: no database, state in memory, and a design that assumes the tracker is a cache rather than a ledger. The second group is the libraries, and this is where aquatic is unusual. The protocol crates for UDP, HTTP and WebTorrent are published separately and can be used on their own, so a client library or a research tool can speak the tracker protocols without adopting the server, and the peer identifier crate stands alone for anyone who needs to fingerprint BitTorrent clients in a swarm. What you give up by choosing aquatic is the breadth of a full tracker product. The top level README is short by design and says so, telling you to refer to the README pages for the respective implementations, and the configuration lives in TOML files handled by a dedicated crate rather than in a web admin panel. If you want a tracker you configure through a browser, this is not it. If you want one you can reason about, measure and put in front of a large swarm, the design choices are in your favour.

## Conclusion

aquatic suits an operator running a public or private tracker who needs the UDP path to hold a large request rate and wants to inspect the behaviour rather than patch an existing tracker, since the UDP, HTTP and WebTorrent implementations are separate crates and the load testers let you measure your own deployment. It is the wrong tool if you need a tracker with persistent state, because all data is stored in memory with no database, and it is the wrong tool if you are not prepared to read the per implementation READMEs, since the top level document deliberately delegates usage instructions. Before you deploy it, read the README of the specific implementation you intend to run, and check the OS requirements in the table, because the UDP build is Unix-like while the HTTP and WebTorrent builds want Linux 5.8 or later.

## FAQ

### Which BitTorrent protocols does aquatic support?

It is built as separate sub-implementations: aquatic_udp for BitTorrent over UDP, aquatic_http for BitTorrent over HTTP optionally over TLS, and aquatic_ws for WebTorrent optionally over TLS. The UDP build needs a Unix-like system, while the HTTP and WebTorrent builds need Linux 5.8 or later.

### Does aquatic need a database?

No. All data is stored in memory, with no database needed, and the README lists this alongside the multithreaded design for handling large amounts of traffic. It also supports forbidding and allowing info hashes, and offers Prometheus metrics.

### How do I load test an aquatic tracker?

The repository ships load test applications for each protocol, aquatic_udp_load_test, aquatic_http_load_test and aquatic_ws_load_test, described as useful for profiling, plus the aquatic_bencher crate for automated benchmarking of aquatic and other trackers.

## Sources

- [greatest-ape/aquatic on GitHub](https://github.com/greatest-ape/aquatic)
- [Issues](https://github.com/greatest-ape/aquatic/issues)
- [License: Apache-2.0](https://github.com/greatest-ape/aquatic/blob/master/LICENSE)
- [README](https://github.com/greatest-ape/aquatic/blob/master/README.md)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/greatest-ape-aquatic
