Torrust-Actix Tracker is a lightweight but incredibly powerful and feature-rich BitTorrent Tracker made using Rust.
Currently, it's being actively used at https://www.gbitt.info/.
This project originated from Torrust-Tracker code originally developed by Mick van Dijke, further developed by Power2All as alternative for OpenTracker and other tracker code available on GitHub.
You can get the latest binaries from releases or follow the installation from scratch instructions below.
git clone https://github.com/Power2All/torrust-actix.git
cd torrust-actix
cargo build --release
Note:
lib/torrust-client(the optional desktop GUI) is excluded from the default build. It requires thefontconfigsystem library and a graphical environment (Slint UI framework). See lib/torrust-client — Optional GUI below for details.
lib/torrust-client is a desktop GUI front-end built with the Slint UI framework.
It is a workspace member but is not compiled by default (default-members excludes it).
# Debian / Ubuntu
sudo apt-get install libfontconfig1-dev
# Fedora / RHEL
sudo dnf install fontconfig-devel
# Arch
sudo pacman -S fontconfig
# Build only the GUI client
cargo build --release -p torrust-client
# Or build the entire workspace including the GUI
cargo build --release --workspace
Run the code using --help argument for using in your environment:
./target/release/torrust-actix --help
Before you can run the server, you need to either have persistence turned off, and when enabled, make sure your database is created and working. See the help argument above how to fix your setup as you wish.
Swagger UI is introduced, and when enabled in the configuration, is accessible through the API via /swagger-ui/.
Sentry.io support is introduced, you can enable it in the configuration and the URL where to push the data to.
To run this application in Docker, we provided a Docker Compose file that you can use to run it locally or remotely.
You can find it in the "docker" folder called "docker-compose.yml", and in order to deploy it, use the following commands:
docker compose build .
docker compose start
Use environment variables to override the configuration settings.
LOG_LEVEL <off | trace | debug | info | warn | error>
LOG_CONSOLE_INTERVAL <UINT64>
TRACKER__API_KEY <STRING>
TRACKER__WHITELIST_ENABLED <true | false>
TRACKER__BLACKLIST_ENABLED <true | false>
TRACKER__KEYS_ENABLED <true | false>
TRACKER__USERS_ENABLED <true | false>
TRACKER__SWAGGER <true | false>
TRACKER__KEYS_CLEANUP_INTERVAL <UINT64>
TRACKER__REQUEST_INTERVAL <UINT64>
TRACKER__REQUEST_INTERVAL_MINIMUM <UINT64>
TRACKER__PEERS_TIMEOUT <UINT64>
TRACKER__PEERS_CLEANUP_INTERVAL <UINT64>
TRACKER__PEERS_CLEANUP_THREADS <UINT64>
TRACKER__PROMETHEUS_ID <STRING>
TRACKER__RTC_INTERVAL <UINT64>
TRACKER__RTC_PEERS_TIMEOUT <UINT64>
TRACKER__TOTAL_DOWNLOADS <UINT64>
TRACKER__RTC_COMPRESSION_ENABLED <true | false>
TRACKER__RTC_COMPRESSION_ALGORITHM <lz4 | zstd>
TRACKER__RTC_COMPRESSION_LEVEL <UINT64>
TRACKER__CLUSTER <standalone | master | slave>
TRACKER__CLUSTER_ENCODING <binary | json | msgpack>
TRACKER__CLUSTER_TOKEN <STRING>
TRACKER__CLUSTER_BIND_ADDRESS <STRING>
TRACKER__CLUSTER_MASTER_ADDRESS <STRING>
TRACKER__CLUSTER_KEEP_ALIVE <UINT64>
TRACKER__CLUSTER_REQUEST_TIMEOUT <UINT64>
TRACKER__CLUSTER_DISCONNECT_TIMEOUT <UINT64>
TRACKER__CLUSTER_RECONNECT_INTERVAL <UINT64>
TRACKER__CLUSTER_MAX_CONNECTIONS <UINT64>
TRACKER__CLUSTER_THREADS <UINT64>
TRACKER__CLUSTER_SSL <true | false>
TRACKER__CLUSTER_SSL_KEY <STRING>
TRACKER__CLUSTER_SSL_CERT <STRING>
TRACKER__CLUSTER_TLS_CONNECTION_RATE <UINT64>
CACHE__ENABLED <true | false>
CACHE__ENGINE <redis | memcache>
CACHE__ADDRESS <STRING>
CACHE__PREFIX <STRING>
CACHE__TTL <UINT64>
CACHE__SPLIT_PEERS <true | false>
SENTRY__ENABLED <true | false>
SENTRY__DEBUG <true | false>
SENTRY__ATTACH_STACKTRACE <true | false>
SENTRY__SEND_DEFAULT_PII <true | false>
SENTRY__DSN <STRING>
SENTRY__MAX_BREADCRUMBS <UINT64>
SENTRY__SAMPLE_RATE <F32>
SENTRY__TRACES_SAMPLE_RATE <F32>
DATABASE__PERSISTENT <true | false>
DATABASE__INSERT_VACANT <true | false>
DATABASE__REMOVE_ACTION <true | false>
DATABASE__UPDATE_COMPLETED <true | false>
DATABASE__UPDATE_PEERS <true | false>
DATABASE__PATH <STRING>
DATABASE__ENGINE <sqlite3 | mysql | pgsql>
DATABASE__PERSISTENT_INTERVAL <UINT64>
DATABASE__CHUNK_SIZE <UINT64>
DATABASE_STRUCTURE__TORRENTS__BIN_TYPE_INFOHASH <true | false>
DATABASE_STRUCTURE__TORRENTS__TABLE_NAME <STRING>
DATABASE_STRUCTURE__TORRENTS__COLUMN_INFOHASH <STRING>
DATABASE_STRUCTURE__TORRENTS__COLUMN_SEEDS <STRING>
DATABASE_STRUCTURE__TORRENTS__COLUMN_PEERS <STRING>
DATABASE_STRUCTURE__TORRENTS__COLUMN_COMPLETED <STRING>
DATABASE_STRUCTURE__TORRENTS__PERSISTENT <true | false>
DATABASE_STRUCTURE__WHITELIST__BIN_TYPE_INFOHASH <true | false>
DATABASE_STRUCTURE__WHITELIST__TABLE_NAME <STRING>
DATABASE_STRUCTURE__WHITELIST__COLUMN_INFOHASH <STRING>
DATABASE_STRUCTURE__WHITELIST__PERSISTENT <true | false>
DATABASE_STRUCTURE__BLACKLIST__BIN_TYPE_INFOHASH <true | false>
DATABASE_STRUCTURE__BLACKLIST__TABLE_NAME <STRING>
DATABASE_STRUCTURE__BLACKLIST__COLUMN_INFOHASH <STRING>
DATABASE_STRUCTURE__BLACKLIST__PERSISTENT <true | false>
DATABASE_STRUCTURE__KEYS__BIN_TYPE_HASH <true | false>
DATABASE_STRUCTURE__KEYS__TABLE_NAME <STRING>
DATABASE_STRUCTURE__KEYS__COLUMN_HASH <STRING>
DATABASE_STRUCTURE__KEYS__COLUMN_TIMEOUT <STRING>
DATABASE_STRUCTURE__KEYS__PERSISTENT <true | false>
DATABASE_STRUCTURE__USERS__ID_UUID <true | false>
DATABASE_STRUCTURE__USERS__BIN_TYPE_KEY <true | false>
DATABASE_STRUCTURE__USERS__TABLE_NAME <STRING>
DATABASE_STRUCTURE__USERS__COLUMN_UUID <STRING>
DATABASE_STRUCTURE__USERS__COLUMN_ID <STRING>
DATABASE_STRUCTURE__USERS__COLUMN_ACTIVE <STRING>
DATABASE_STRUCTURE__USERS__COLUMN_KEY <STRING>
DATABASE_STRUCTURE__USERS__COLUMN_UPLOADED <STRING>
DATABASE_STRUCTURE__USERS__COLUMN_DOWNLOADED <STRING>
DATABASE_STRUCTURE__USERS__COLUMN_COMPLETED <STRING>
DATABASE_STRUCTURE__USERS__COLUMN_UPDATED <STRING>
DATABASE_STRUCTURE__USERS__PERSISTENT <true | false>
API_0_ENABLED <true | false>
API_0_SSL <true | false>
API_0_BIND_ADDRESS <STRING>
API_0_REAL_IP <STRING>
API_0_SSL_KEY <STRING>
API_0_SSL_CERT <STRING>
API_0_KEEP_ALIVE <UINT64>
API_0_REQUEST_TIMEOUT <UINT64>
API_0_DISCONNECT_TIMEOUT <UINT64>
API_0_MAX_CONNECTIONS <UINT64>
API_0_THREADS <UINT64>
API_0_TLS_CONNECTION_RATE <UINT64>
HTTP_0_ENABLED <true | false>
HTTP_0_SSL <true | false>
HTTP_0_BIND_ADDRESS <STRING>
HTTP_0_REAL_IP <STRING>
HTTP_0_SSL_KEY <STRING>
HTTP_0_SSL_CERT <STRING>
HTTP_0_KEEP_ALIVE <UINT64>
HTTP_0_REQUEST_TIMEOUT <UINT64>
HTTP_0_DISCONNECT_TIMEOUT <UINT64>
HTTP_0_MAX_CONNECTIONS <UINT64>
HTTP_0_THREADS <UINT64>
HTTP_0_TLS_CONNECTION_RATE <UINT64>
HTTP_0_RTCTORRENT = <true | false>
UDP_0_ENABLED <true | false>
UDP_0_BIND_ADDRESS <STRING>
UDP_0_UDP_THREADS <UINT64>
UDP_0_WORKER_THREADS <UINT64>
UDP_0_RECEIVE_BUFFER_SIZE <UINT64>
UDP_0_SEND_BUFFER_SIZE <UINT64>
UDP_0_REUSE_ADDRESS <true | false>
UDP_0_USE_PAYLOAD_IP <true | false>
UDP_0_SIMPLE_PROXY_PROTOCOL <true | false>
UDP_0_RECEIVE_METHOD <auto | recvmmsg | io_uring | rio>
database.chunk_size controls how many rows the tracker writes per SQL transaction when it flushes torrent/user updates to the database (once per persistent_interval). Instead of committing the whole sync batch in a single long-running transaction — which holds row/foreign-key locks for the entire batch and can block other applications writing to the same database (e.g. a website doing DELETE/UPDATE, leading to lock-wait timeouts) — the tracker commits every chunk_size rows, releasing locks frequently.
[database]
chunk_size = 1000 # rows per transaction (default: 1000; 0 = commit the whole batch in one transaction)
Lower the value (e.g. 500 or 250) if another application sharing the database still experiences lock contention; raise it (or set 0) for maximum write throughput when the tracker owns the database exclusively. Applies to the high-volume torrents and users sync tables on MySQL, PostgreSQL, and SQLite.
Every /api/... endpoint (and /stats, /metrics) is protected by the API key configured in tracker.api_key (or the TRACKER__API_KEY environment variable). The key can be supplied in two ways:
Authorization header (recommended) — keeps the secret out of URLs, access logs and browser history:Authorization: Bearer <api_key>
The Bearer prefix is optional; a bare Authorization: <api_key> is also accepted.
token query-string parameter (legacy) — kept for backwards compatibility:GET /api/torrents?token=<api_key>
If both are present, the Authorization header takes precedence. The key is compared in constant time. Example:
# Preferred — token in the header
curl -H "Authorization: Bearer <api_key>" http://127.0.0.1:8080/api/torrents
# Legacy — token in the query string
curl "http://127.0.0.1:8080/api/torrents?token=<api_key>"
RtcTorrent is the built-in WebRTC peer-to-peer library that lets a browser (or Node.js process) act as a BitTorrent seeder or leecher without any browser plugin or native binary. It uses the standard HTTP announce endpoint with additional query parameters for WebRTC signalling.
A full protocol white paper is available in RtcTorrent.md.
Browser (leecher) ──announce + rtctorrent=1──► Tracker (Torrust-Actix)
◄── SDP offer from seeder ──
Browser ──answer + rtcanswerfor=<peer_id>────► Tracker
Seeder ──poll (announce) ───────────────────► Tracker
◄── SDP answer ──
WebRTC Data Channel established directly between Browser ↔ Seeder
cd lib/rtctorrent
npm install
npm run build # produces dist/rtctorrent.browser.js (minified)
npm run dev # watch mode for development
The build outputs two bundles:
| File | Target | Use |
|---|---|---|
dist/rtctorrent.browser.js |
Browser (<script>) |
Website player/downloader |
dist/rtctorrent.node.js |
Node.js (require) |
CLI seeder, server-side |
Copy dist/rtctorrent.browser.js to your web server's static assets, then include it in your HTML:
<script src="https://github.com/Power2All/torrust-actix/raw/v4.2.15/assets/rtctorrent.browser.js"></script>
```html
RtcTorrent Demo$ claude mcp add torrust-actix \
-- python -m otcore.mcp_server <graph>