Browse docs
Docs / Reference / Engine Config File (config.json)

Engine Config File (config.json)

The Swarmfile engine reads its startup configuration from three sources, in this order of precedence:

  1. Environment variables (SWARMFILE_*) - always win.
  2. The config.json file - the subset of settings documented below.
  3. Built-in defaults - a released build ships pointing at Swarmfile's hosted service, so an unconfigured engine connects to production rather than nothing.

Most people never touch this file: the desktop tray writes the keys it manages for you, and a normal sign-in fills in the rest. You edit config.json directly for headless and unattended setups - a NAS/seed node, a render-farm worker, a VM, or any machine that boots the engine from autostart rather than a signed-in tray session - where there's no UI to click and, on macOS/Windows, no shell environment for the engine to inherit exported variables from.

Where the file lives#

PlatformDefault path
macOS / Linux~/.config/swarmfile/config.json (respects $XDG_CONFIG_HOME)
Windows%LOCALAPPDATA%\Swarmfile\config.json

To point the engine at a specific file instead - e.g. one config per project on a multi-tenant node - set SWARMFILE_CONFIG=/path/to/config.json. That overrides the default location entirely.

Editing safely#

A few things are worth knowing before you hand-edit this file:

  • Restart the engine after editing. The file is read once at startup. A handful of values are also applied live (cache size, throttle), but treat a restart as required for a change to take effect.
  • A single syntax error discards the whole file. If the JSON doesn't parse, the engine logs a warning and starts with defaults - the hosted hub, but no org_id or project_id, so the drive has nothing behind it. One trailing comma or misspelled key silently drops those along with everything else. Validate your JSON before restarting.
  • A UTF-8 byte-order mark (BOM) is tolerated. Windows Notepad and PowerShell 5.1's -Encoding UTF8 prepend one; the engine strips it. Still, prefer a plain UTF-8 editor.
  • Environment variables override the file. If a launcher (systemd unit, Docker -e, a scheduled task) sets SWARMFILE_HUB_URL, editing hub_url in the file will appear to do nothing. Check what actually took effect with --print-env-vars (below).
  • Don't fight the tray. For keys the tray or swarmfile CLI manage (mount point, seed mode, hub-only, cache size, throttle, LAN placement, branch), prefer their controls - the tray may rewrite the file and overwrite a manual edit. Hand-editing is for machines with no tray.

Connecting to the hosted service#

A released build ships pointing at Swarmfile's production service, so you do not need to configure the hub or identity provider by hand. With nothing set, the engine defaults to:

SettingDefault
hub_urlhttps://hub.swarmfile.com
oidc_issuerhttps://id.swarmfile.com
oidc_client_idswarmfile-engine

A headless machine on the hosted service therefore only needs to say which org and project it serves and supply a credential - org_id, project_id, and one of SWARMFILE_API_KEY or SWARMFILE_OIDC_REFRESH_TOKEN (see below). Set hub_url, oidc_issuer, or oidc_client_id only when you run a self-hosted or Enterprise hub on your own domain.

Keys you can set in the file#

Every key is optional. Booleans are JSON booleans (true / false) in the file - the true/1 string form is only for the environment-variable equivalents.

KeyTypeDefaultEnv overrideWhat it does
hub_urlstringhttps://hub.swarmfile.comSWARMFILE_HUB_URLHub API base URL. Override only for a self-hosted / Enterprise hub.
org_idstring(none)SWARMFILE_ORG_IDMulti-tenant org id; the hub URL is prefixed with /orgs/{org_id}.
project_idstring(none)SWARMFILE_PROJECT_IDScope every metadata operation to one project (required for headless/seed nodes).
branchstringproject mainSWARMFILE_BRANCHBranch this mount is checked out to at boot.
office_idstringdefaultSWARMFILE_OFFICE_IDPeer-discovery grouping label.
oidc_issuerstringhttps://id.swarmfile.comSWARMFILE_OIDC_ISSUEROIDC issuer URL. Override only for a self-hosted IdP.
oidc_client_idstringswarmfile-engineSWARMFILE_OIDC_CLIENT_IDOIDC client id.
encryption_project_idstringfalls back to project_idSWARMFILE_ENCRYPTION_PROJECT_IDProject whose hub-managed key encrypts blocks.
read_onlyboolfalseSWARMFILE_READ_ONLYForce a kernel-level read-only mount (guest sessions).
session_kindowner|member|guestownerSWARMFILE_SESSION_KINDActive session role (drives the tray's "Guest (read-only)" badge).
hub_onlyboolfalseSWARMFILE_HUB_ONLYDisable all P2P (Iroh/QUIC/mDNS/gossip); serve every read over HTTPS from the hub.
seed_modeboolfalseSWARMFILE_SEED_MODERun as a NAS/seed node (pin all blocks, mirror to R2, no VFS mount).
ec_lan_placementboolfalseSWARMFILE_EC_LAN_PLACEMENTDeliberately spread erasure-coded shards across LAN peers.
lan_from_officeboolfalseSWARMFILE_LAN_FROM_OFFICETreat same-office peers as LAN peers even when mDNS discovery is unavailable. LAN peers are normally found by mDNS; on networks that block mDNS multicast (many corporate/VLAN'd networks) that finds nothing, so peers read as WAN and LAN shard placement has no one to spread across. Turn this on when you know your office_id members share a LAN. Pairs with ec_lan_placement.
throttle_enabledbooltrueSWARMFILE_THROTTLE_ENABLEDEnable bandwidth throttling / QoS.
site_download_bandwidth_mbpsnumber(unset)SWARMFILE_SITE_DOWNLOAD_BANDWIDTH_MBPSDownload bandwidth cap in Mbps.
site_upload_bandwidth_mbpsnumber(unset)SWARMFILE_SITE_UPLOAD_BANDWIDTH_MBPSUpload bandwidth cap in Mbps.
cache_max_bytesnumber10737418240 (10 GiB)SWARMFILE_CACHE_MAX_BYTESLocal block-cache size cap, in bytes.
changeset_idle_secsnumber300SWARMFILE_CHANGESET_IDLE_SECSIdle seconds before a project-scoped changeset auto-commits (0 disables grouping).
attr_cache_secsnumber2SWARMFILE_ATTR_CACHE_SECSmacOS only: kernel attribute-cache ceiling (0 keeps FUSE-T's 5-60s default).
stream_in_flightboolfalseSWARMFILE_STREAM_IN_FLIGHTLet this mount open a file that is still uploading - it appears at its full eventual size and reads work, waiting briefly where bytes have not landed. Off by default; see the note below before turning it on.
mount_pointstring/tmp/swarmfile (Unix), S: (Windows)SWARMFILE_MOUNT_POINTWhere to mount the drive - a directory on Unix, a drive letter on Windows.
mount_point_auto(managed)--Do not set. The engine writes this to record a drive letter it auto-selected; hand-editing it breaks the "don't relocate a letter the user chose" logic.

Settings that are environment-variable-only#

Many settings can be tuned via SWARMFILE_* env vars but are not readable from config.json - the file supports only the keys in the table above. Notable env-only settings include:

  • Credentials: SWARMFILE_OIDC_REFRESH_TOKEN (non-interactive OIDC), SWARMFILE_API_KEY (project-scoped headless key - takes precedence over a refresh token), SWARMFILE_ENCRYPTION_KEY, SWARMFILE_SWARM_KEY. Credentials are deliberately kept out of the file.
  • Paths & identity: SWARMFILE_CACHE_DIR, SWARMFILE_IROH_DIR, SWARMFILE_USER_ID, SWARMFILE_MACHINE_ID.
  • Encryption toggle/mode: SWARMFILE_ENCRYPTION_ENABLED, SWARMFILE_EC_ENABLED (on/off/auto).
  • Networking: SWARMFILE_IROH_BIND_ADDR, SWARMFILE_IROH_PUBLIC_ADDR, SWARMFILE_HEALTH_PORT.
  • QoS / office hours: SWARMFILE_OFFICE_HOURS_START / _END, SWARMFILE_OFFICE_HOURS_WAN_PCT, SWARMFILE_OFF_HOURS_WAN_PCT, SWARMFILE_DSCP_INTERACTIVE, SWARMFILE_DSCP_BACKGROUND.
  • Seed tuning: SWARMFILE_SEED_POLL_INTERVAL, SWARMFILE_SEED_UPLOAD_CONCURRENCY.
  • Runner (headless CI): SWARMFILE_RUNNER_MODE - watches SWARMFILE_BRANCH for commits/tags matching a rule in .swarmfile/runner.yml and runs it. Env-only by design, no config.json key or tray toggle - see Runner (Headless CI). Mutually exclusive with seed_mode.
  • Streaming an upload in progress: SWARMFILE_STREAM_IN_FLIGHT (see the key above), SWARMFILE_STREAM_BUFFER_SECS, SWARMFILE_STREAM_READ_WAIT_SECS - env-only, no config.json key. STREAM_BUFFER_SECS (default 30) is how many seconds of playback a fetch --follow job keeps buffered ahead of the reader; it is seconds rather than bytes because 30 s of a proxy and 30 s of a full-resolution master are wildly different byte counts and one figure would be wrong for both. STREAM_READ_WAIT_SECS (default 15) is how long a read of a not-yet-uploaded range waits before giving up - see below.
  • Misc: SWARMFILE_XREF_PREFETCH, SWARMFILE_DOCTOR_PERIOD_SECS, SWARMFILE_OTEL_ENDPOINT, SWARMFILE_OTEL_SERVICE_NAME.

A note on stream_in_flight#

Worth reading before switching it on, because the default is deliberate rather than cautious-by-habit.

A read into a range that has not been uploaded yet has to wait, and this runs on a filesystem operation thread. An operation that waits too long does not stall one read - it takes the whole drive with it. The wait is therefore strictly bounded (SWARMFILE_STREAM_READ_WAIT_SECS, default 15 s, and 0 does not mean "forever" - it falls back to the default), and a read that outruns the upload returns a retryable "not yet" rather than an I/O error, because an application that sees an I/O error part way through a file will usually conclude the file is damaged and discard your document.

That bound has not yet been measured against a real editing application on both platforms. Until it has, this is something to switch on deliberately, per machine, for a project that needs it.

Scope worth knowing:

  • It applies only to files with no committed version yet - a new file landing for the first time. A file you are already reading never changes size or content because somebody started a new save.
  • A file that is streaming reports the size it is going to be, not 0. Without that, nothing could read it: no application asks for bytes past the end of an empty file.
  • If the uploading machine is on the same LAN, it serves those blocks directly from its own disk, before they reach the cloud. Over a WAN it does not - that would carry every block twice on the same contended uplink.

And the limit that no setting changes: this decides which bytes arrive first, not how fast the link is. A 4 TB file on a 100 Mbit/s uplink delivers about 12 MB/s however well it is ordered.

Engine command-line flags#

Beyond reading config.json, the swarmfile-engine binary takes a handful of one-shot flags - useful on a headless node where there's no tray to click.

Answered immediately - about this binary, or a running engine:

FlagWhat it does
--statusEngine, hub, peers, and pending work at a glance. Queries a running engine; falls back to a one-shot read of local state if none is running.
--print-env-varsThe resolved SWARMFILE_* values this build consumed, secrets redacted, with a footer naming the config file it loaded.
--capabilitiesThe compiled feature set of this binary - which optional features it was built with.
--version, -VPrint the version and exit.
--help, -hPrint the flag list and exit.

Lifecycle - against a running engine:

FlagWhat it does
--pausePause sync without unmounting the drive.
--resumeResume after --pause.
--quitAsk the running engine to drain in-flight work and stop.

--help and --version answer before the engine reads any config, so they work on a broken or unconfigured install. For day-to-day version-control and mount operations, use the swarmfile CLI - it drives the same engine over its control socket - rather than these flags.

The engine's own --help also lists offline/pinning flags (--pin, --prepare-offline, and related). These currently run only while the engine is stopped, so they can't be driven against a live mount and aren't part of the normal headless workflow. To force a scope resident for offline or render-farm use against a running engine, use swarmfile hydrate instead.

Verifying what actually took effect#

Because three sources feed the final config, print the resolved values the engine will use - with secrets redacted, and a footer naming the config file it loaded:

swarmfile-engine --print-env-vars

swarmfile doctor (or the standalone swarmfile-doctor) then confirms the resolved hub URL, org, and credentials actually reach the hub. See CLI: swarmfile-doctor.

Example: a headless seed node#

On the hosted service the hub and IdP are already the defaults, so a seed node only names its org and project:

{
  "org_id": "org_abc123",
  "project_id": "proj_xyz789",
  "seed_mode": true,
  "cache_max_bytes": 107374182400
}

(On a self-hosted or Enterprise hub, add hub_url, oidc_issuer, and oidc_client_id for your own domain.)

Pair this with a credential in the environment - SWARMFILE_API_KEY=sf_key_… for a project-scoped key, or SWARMFILE_OIDC_REFRESH_TOKEN=… - since credentials aren't stored in the file. See Deployment Topologies and Self-Hosted Seed Nodes for the full headless-node walkthrough, Network Requirements for exactly what a machine using this file needs to reach, and Deploying to Your Team for pre-staging this file across a fleet.