Local debrid libraries and portable zurgtorrents
A local library takes its membership from portable .zurgtorrent files. It
appears in the normal WebDAV, HTTP and provider directories. Importing files,
listing them and refreshing the catalog do not add torrents or resolve download
links. Playback resolves the requested file through your configured account.
Export a library
From the exporting instance's working directory:
./zurg --config config.yml export-torrents data --provider realdebrid --output exported/realdebrid
--provider is the configured account name, including a custom name. Omit
it to export all supported debrid copies. The input can also be one runtime
cache file, a legacy dump/ directory, or an existing portable catalog.
For a local library, export its source directory (torrents/<account>), which
preserves its optional references to other providers.
Export is offline. It validates all inputs and destination collisions before
writing, reports and skips runtime entries without selected file metadata, merges releases by hash, and writes <hash>.zurgtorrent. Existing
identical exports are safe to repeat. For a bulk migration containing malformed
legacy cache entries, --skip-invalid exports the valid entries and reports how
many were omitted. Without it, the first invalid entry aborts before any writes. --replace permits replacing a portable
export of the same hash; it never authorizes overwriting a runtime cache.
Only the exported files are intended for sharing. data/*.zurgtorrent remains
private runtime state. A .zurgbackup also contains account credentials and is
an instance backup, not a shareable library.
Receive a library
Put the exported files in torrents/rd-local/, then configure the receiving
account:
providers:
- name: rd-local
type: realdebrid
token: YOUR_OWN_TOKEN
download_tokens: # Optional bandwidth fallback on another RD account.
- SECOND_RD_TOKEN
library:
source: local
# Optional; defaults to torrents/<account-name>.
path: torrents/rd-local
- name: tb-online
type: torbox
token: YOUR_OWN_TORBOX_TOKEN
# Omitted library block means the provider owns this account's catalog.
On Real-Debrid and AllDebrid, download_tokens uses the same local catalog as
its provider entry. The second RD account above needs no directory, and its
torrent library is not imported.
These are fallback credentials used when the active download token's bandwidth
allowance is exhausted; they do not force every download through the second
account. Adding a second RD entry under providers instead creates a separate
catalog with its own directory. All credentials remain in the config and are
excluded from portable exports.
TorBox also accepts download_tokens, but its token rotation does not map the
stored torrent/file IDs to IDs on the other account. Use separate TorBox
provider entries for separate accounts, each with its own local catalog.
Premiumize, Offcloud and Debrid-Link accounts can hold a local library too. None of them has a portable file reference. So like TorBox each one adds the hash to its own account on first playback and matches the files by path and size. Use one provider entry per account.
Restart after changing account configuration. File additions, replacements and
removals are picked up by the normal refresh loop. Each directory is scanned
one level deep. Paths must be distinct directories below torrents/, so normal
backups include them. An unreadable directory or invalid replacement retains
the last valid in-memory entry and logs the problem. After restarting, an
invalid file must be fixed before it can enter the catalog.
The same manifest can be copied into an AllDebrid or TorBox account's local directory. It contains content identity, not a provider account name. The same hash across accounts appears once with several sources, using the existing account preference and failover order. Duplicate files for a hash within one directory use the first filename in sorted order; keep one manifest per hash.
Local catalog membership survives removal from the provider's online library. Renames, tags, IMDb IDs and file deletions are saved back into the manifests. Removing a local release removes its source documents; it does not delete provider torrents. Removing a release with online copies also deletes those online copies, as the normal whole-release delete does.
Local accounts are not targets for watchlists, magnet uploads or torrent-file
uploads. Add entries by importing manifests. add_torrents: false still lets
RD/AD redeem an existing shared reference but prevents playback from creating a
provider-side attachment when one is needed.
Offload an online account into a local library
AllDebrid takes at most 1000 magnets per account, and Real-Debrid accounts fill
up too. A finished release does not need its torrent on the account to keep
playing. A Real-Debrid /d/ link keeps working after the torrent is deleted,
and an AllDebrid locked /f/ link keeps working after the magnet is deleted.
Offloading relies on that. Zurg writes a finished release into a local library
on the same service, then deletes the torrent from the online account, which
frees its slot. The release keeps its folder in the mount and plays from the
saved links.
Configure two entries for the same account, one online and one local:
providers:
- name: ad
type: alldebrid
token: YOUR_AD_TOKEN
library:
offload_to: ad-local # the local entry below
offload_after_mins: 30 # optional, 30 is the default
- name: ad-local
type: alldebrid
token: YOUR_AD_TOKEN # the same token
library:
source: local # manifests live in torrents/ad-local/
New releases keep arriving on ad. After every complete listing of that
account, and every five minutes, zurg moves the releases that qualify, one at
a time. A release qualifies when:
-
It has been complete on the account for
offload_after_mins, counted from when this zurg process first saw it complete. A restart starts the wait again. -
Every file has a working link on that account that another account could redeem. A release with any file missing one stays online.
-
It is healthy, not being repaired, and no instance of it is still downloading. No repair pass or download client holds its torrent.
-
No qBittorrent job from Sonarr or Radarr still lists it. Turn on Remove Completed Downloads in the *arr so a job is removed after its import. Otherwise the release stays online until you remove the job.
-
Acquisition did not add it within the last hour.
-
Moving it changes no directory it is in and keeps its folder name. A directory with a
provider:filter naming the online account would lose it, so such a release stays online.
The order is fixed. The manifest <hash>.zurgtorrent is written into the local
library first, the release joins the local library next, and only then is the
torrent deleted from the online account. If the manifest cannot be written,
nothing is deleted. If the delete fails, the online copy stays beside the local
one and the next refresh shows whether the torrent is still there. A manifest
the local library already has for the release is updated in place rather than
written twice. The online account's links in it are refreshed, its names and
edits follow the release as the mount shows it, and the other service's links
are kept.
The release leaves __ad__ and appears under __ad-local__. Every other
directory, __all__ and your own included, keeps listing it under the same
name. No media server scan is started, because nothing a media server indexes
has changed. Point Plex and other media servers at those directories rather
than at a per-account one.
With both entries on one token, local playback can attach a release to the same account again (see below), and that torrent then shows up in the online listing. Zurg never offloads a release whose online torrent is such an attachment, or while local playback is adding one, because deleting it would break the playback that just obtained it.
Only Real-Debrid and AllDebrid can offload. TorBox, Premiumize, Offcloud and
Debrid-Link have no link that survives the torrent, so their local playback
adds the torrent back and an offload would free nothing. Zurg refuses
offload_to on those accounts.
The dashboard can move a single release as well. On a release's page, the
Accounts table shows Move to local library next to each Real-Debrid or
AllDebrid copy when a local library of the same type exists, even without
offload_to. When the release cannot move yet, the button is disabled and says
why. The account's settings on the config page offer the same choice and show
how many releases moved since zurg started, and the last error.
What travels in the file
The versioned JSON format has format: "zurgtorrent" and numeric version: 1.
It carries the infohash, release names, added timestamp, rename, tags, IMDb ID,
and selected file paths, sizes and optional renames. References are optional:
No account names, credentials, provider torrent/file IDs, CDN URLs, MediaInfo
input URLs, Plex IDs, repair state or deletion queues are exported. The importer
rejects unknown fields and credential-bearing or unexpected reference URLs.
It does not fetch URLs while validating a manifest. Usenet keeps its .nzb
source format; NZB runtime caches cannot be exported as portable torrents.
Playback and limits
Local tracking changes who owns the catalog. It does not guarantee that a provider still has the bytes or can serve them. Account access, allowed network locations, active slots, quotas and rate limits still apply.
RD and AD use shared locked references when present. Hash-only manifests, and an RD reference the API definitively reports missing, can establish content on the recipient's account. TorBox always needs that account attachment and first reuses a matching torrent already on the recipient account. Adds use the existing provider pacing and are serialized per account. An add waits for a free slot when the account reports its slot count or zurg knows it. AllDebrid, Premiumize and Offcloud report none, so the add goes ahead and a full account refuses it. An uncertain add is held for 30 minutes before another attempt; a preparing torrent is checked only when playback is requested again.
Recipient IDs and resolved native file handles stay privately in
data/local-torrents/. That record survives a restart and is included in normal
backups. Zurg never deletes those attachments automatically: an idempotent add
may have returned a torrent the recipient already owned. Offloading leaves
them alone as well. Provider failures
leave the local entry visible and back off rather than starting background
repair or repeating an add for every scan.
Local archive releases list their source volumes without automatic extraction or background inspection. An explicit path inside an archive can still invoke the archive reader. Automatic MediaInfo probing and next-file prefetch are suppressed on entries with local copies.
Migrate an old dump
Export dump/ with the command above, put the results in the receiving
account's torrents/<name>/ directory and enable library.source: local.
Turn off load_dumped_torrents after migration. The old opt-in __dump__
reader remains for compatibility; new local libraries do not use it. Runtime
caches lacking an account type need to be re-exported from an instance that
knows their provider before they can be shared.
Backups written by this build use format 2 to include the new durable roots. The restore command still reads format 1 backups. Older builds refuse format 2 rather than silently dropping a local library.