Self-Hosted Seed Nodes
Swarmfile is LAN-first: peers on the same network exchange file data directly and only fall back to cloud storage when no local copy is available. A self-hosted seed node extends that further by letting a machine you own - a NAS, an old workstation, a dedicated on-prem box - participate permanently in the swarm as a warm cache tier.
What a seed node is#
A seed node is just a machine running Swarmfile with seeding turned on. It joins the peer-to-peer swarm like any other client, but instead of only holding what a given user happens to have opened, it holds a persistent, shared cache that the rest of your office can pull from.
The practical benefit shows up for offices that already have a lot of project data sitting on local infrastructure: rather than every workstation re-fetching the same large files from cloud storage over and over, they fetch from the seed node on the LAN instead. That's faster, and it takes load off your egress and off the cloud fallback path entirely for anything the seed already holds.
A seed keeps two things in sync. It walks the project and fetches every block, mirroring the whole project to cloud storage - so the cloud copy is always complete and no editor ever has to be the one who pulls a file from the cloud first. Locally, it keeps a warm cache bounded by SWARMFILE_CACHE_MAX_BYTES: once full, the block store evicts the least-recently-used blocks, and an evicted block is simply re-fetched on demand (from a peer or the cloud) the next time someone reads it. Size that budget to the working set you want resident - the template ships 100 GiB; a NAS serving a multi-TB production wants 1 TiB or more. A cache smaller than the project still helps (hot data stays local), but the bigger the cache, the more of the office's reads never touch the WAN at all.
One thing worth being precise about: on the standard managed (encrypted) tier, what the seed node caches is ciphertext - reading it still needs a decryption key fetched live from the hosted hub. A seed node is a warm, on-premises cache that speeds up your office and reduces cloud round-trips, not an independently readable offline copy of your data. See Data Portability & Offboarding for what that does and doesn't mean if the hosted service is ever unreachable.
Plan requirement#
Running a seed node requires the Pro plan or above.
It's also mutually exclusive with cloud-only mode: a mount can't be both a pure cloud-only client and a seed node at the same time. If a machine is configured for cloud-only operation, you'll need to turn that off before enabling seeding on it.
The hub also gates whether a self-hosted node is allowed to announce itself to the swarm at all, based on your org's plan entitlement. If a seed or NAS node is running under a plan that doesn't include the seeding entitlement, its announces are refused outright - a hard block rather than a warning you might miss in a log.
Enabling seeding#
For a machine that's already running the regular Swarmfile client, toggle seeding with:
swarmfile seed enable
and to turn it back off:
swarmfile seed disable
Both commands restart the engine to apply the change, so expect a brief interruption on that machine.
For a dedicated, headless machine - a NAS or a box that isn't otherwise being used as anyone's workstation - run the swarmfile-engine daemon directly instead of the Desktop App (the Desktop App is just a GUI wrapper around the same engine), then run swarmfile seed enable against it exactly as above.
Don't confuse this with the standalone
swarmfile-seedbinary. Despite the name, it isn't a way to run a seed node - it's a one-shot admin tool that uploads a single local file straight into the hub and exits, useful for scripted bulk ingestion. See swarmfile-seed for its reference.
Enrolling an office cache from the dashboard#
For a machine that has no Desktop App - the NAS, the edit-bay Mac mini, the small box next to the switch - set it up from an env file instead. The dashboard generates that file for you:
- Open Settings → Office caches and click Add an office cache.
- Name the office (a stable, lowercase id like
london) and pick the project the cache serves. - The wizard shows the complete
seed.envonce - it contains a freshly minted project-scoped API key. Save it on the cache machine as/etc/swarmfile/seed.env(mode 0600), install the engine, and start the engine service with that env file;SWARMFILE_SEED_MODE=trueis already in it, so there's no toggle to run.
The generated file carries every value a headless seed needs, including the scope (SWARMFILE_ORG_ID and SWARMFILE_PROJECT_ID alongside SWARMFILE_OFFICE_ID) - a seed whose scope is missing pins nothing. The credential is a project-scoped API key: no interactive login on the box, and no refresh token to rotate away. It is an organization credential, not a personal one - it keeps working if the person who created it leaves the team, and it stops only when someone revokes it under Settings → API keys (at which point the cache shows offline here and the offline alert below fires).
One cache serves one project; run one cache per office per project. The same page lists every cache with its online/offline state, last announce, and the bytes it served this week; a weekly email report goes to the organization's owners and admins, and a cache that goes silent for a day triggers one alert email per outage. Both can be muted under Settings → Notifications ("Weekly office cache report", "Office cache offline for a day").
Installing on Windows#
On Windows, run the seed as a scheduled task that loads seed.env and supervises the engine. Save the generated seed.env somewhere the SYSTEM account can read (e.g. C:\ProgramData\Swarmfile\seed.env), then create the wrapper and the task from an elevated PowerShell:
$wrapper = "$env:ProgramData\Swarmfile\run-seed.cmd"
@"
@echo off
setlocal
for /f "usebackq eol=# tokens=1,* delims==" %%A in ("C:\ProgramData\Swarmfile\seed.env") do set "%%A=%%B"
:loop
"C:\Program Files\Swarmfile\swarmfile-engine.exe"
timeout /t 5 /nobreak >nul
goto loop
"@ | Set-Content -Path $wrapper -Encoding ASCII
$action = New-ScheduledTaskAction -Execute "$env:SystemRoot\System32\cmd.exe" -Argument "/c `"$wrapper`""
$trigger = New-ScheduledTaskTrigger -AtStartup
$settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -ExecutionTimeLimit ([TimeSpan]::Zero)
$principal = New-ScheduledTaskPrincipal -UserId "SYSTEM" -LogonType ServiceAccount -RunLevel Highest
Register-ScheduledTask -TaskName "SwarmfileSeed" -Action $action -Trigger $trigger -Settings $settings -Principal $principal
Start-ScheduledTask -TaskName "SwarmfileSeed"
The task starts the engine at boot as SYSTEM - no sign-in needed - and the wrapper restarts it if it exits, so a crash recovers headlessly. To remove the seed, run Stop-ScheduledTask -TaskName SwarmfileSeed and Unregister-ScheduledTask -TaskName SwarmfileSeed -Confirm:$false, then delete the wrapper; the seed.env holds a credential, so remove it yourself when you mean to. After the first announce the cache appears on the Office caches page like any other.
Deliberate LAN shard placement#
By default, which peer ends up holding which erasure-coded shard of a file is opportunistic - whoever happened to fetch or cache it holds it. That's fine for most teams, but it means fault tolerance is a byproduct of usage patterns rather than something you can rely on.
If you want guaranteed redundancy across your office instead - so that losing any single machine doesn't put a file's availability at risk - turn on deliberate placement:
swarmfile ec-placement enable
This rendezvous-hashes each shard across your office roster at a replication factor of 3, so every shard has three specific, deterministic homes on your network instead of landing wherever caching happened to put it. Like swarmfile seed enable, this restarts the engine.
Reach for this when you have a real office roster of machines and want predictable, guaranteed fault tolerance - not just "probably cached somewhere."
One thing worth being precise about: a seed node's own behavior doesn't depend on whether deliberate placement is on. A seed node always walks the full project tree and fetches every block, unconditionally, so the cloud copy is guaranteed complete - that's a stronger, whole-project guarantee than deliberate placement's replication-factor-of-3, not something deliberate placement adds to. What stays on the seed's own disk is its warm cache (bounded by SWARMFILE_CACHE_MAX_BYTES, see above), not an unbounded mirror: "complete" here means every block has been fetched and mirrored by the seed, with recently used blocks resident for LAN reads. Deliberate placement is what upgrades your regular (non-seed) peers from opportunistic to guaranteed coverage; if every machine in your roster is already a seed node, the cloud always has everything and nothing is left to chance for recovery.
This doesn't require a literal office LAN. office_id is a grouping label, not a network check - any set of peers that share one office_id join the same placement roster together, whether or not they can reach each other on a local network at all. That's the pattern for a cloud-hosted render farm: set a matching office_id on each node, and leave --lan-from-office off (that flag exists to fold regular peers on a real LAN into the roster when mDNS can't discover them; it's not relevant when there's no LAN). Leaving it off also keeps these nodes correctly classified as WAN traffic rather than wrongly exempted from the local bandwidth throttle - egress is never billed on any plan either way. See Deployment Topologies for the render-farm case end to end.
For context, files are erasure-coded Reed-Solomon 10+4 by default, and that scheme is adaptive: it exists primarily to mask WAN latency, so once two or more LAN peers are present for a project it can automatically back off from the full redundancy it uses over a pure cloud connection. Deliberate placement overrides that automatic behavior - when you explicitly want guaranteed office-wide redundancy rather than whatever the adaptive default decides, ec-placement takes the decision out of the engine's hands. For more on the underlying security and isolation model, see Security.
Inspecting shard placement#
To see exactly where a given file's shards actually live, run:
swarmfile shards <path>
This shows, per shard: which peer holds it, whether it's a data shard or a parity shard, and whether the machine you ran the command on currently holds a copy itself. It's the tool to reach for when you want to confirm deliberate placement actually took effect, or just to understand a file's current redundancy without guessing.