Skip to content
Go back

Mozilla Sync Server Self-Hosted: Still Viable?

By SumGuy 9 min read
Mozilla Sync Server Self-Hosted: Still Viable?
Contents

Firefox Sync Has a Long, Weird History, Let’s Talk About It

If you’ve been self-hosting long enough, you probably remember the original Firefox Sync server. Python-based, held together with hope and pip install, and officially deprecated back when most of us still thought “cloud” was a weather phenomenon. Mozilla killed the old syncserver project, rewrote the whole thing in Rust (because it’s Rust, and it’s 2026, and everything is Rust now), and quietly kept it open source.

The current stack is called syncstorage-rs (the sync data backend) and tokenserver-rs (the piece that maps Firefox Account identities to storage nodes). These are the actual services powering sync.services.mozilla.com right now, not some experimental side project. Mozilla runs them in production and publishes the code on GitHub. That’s genuinely good news for self-hosters.

The bad news? You’re going to need to understand exactly how the auth chain works before you touch a single compose file, or you’ll spend a Sunday afternoon staring at “Sync failed” with no useful error.


What Firefox Sync Actually Syncs

Before you commit to this, know what you’re getting. Firefox Sync handles:

All of this is encrypted client-side before it leaves your browser. The encryption keys are derived from your Firefox Account credentials using a process called FxA Key Stretching, which means Mozilla (or you, if you’re self-hosting the storage) never sees your plaintext data. You’re holding the keys. The server just stores encrypted blobs it can’t read.

That’s worth repeating: even on Mozilla’s servers, they can’t read your sync data. Client-side E2EE is baked in. This changes the privacy calculus somewhat, but sovereignty over your own data still has real value, and we’ll get into that.


The Architecture (Don’t Skip This)

Here’s where people get tripped up. Firefox Sync has two distinct services:

syncstorage-rs, stores the actual sync records (bookmarks, history, etc.) in a database. This is what your browser talks to when it pushes or pulls data.

tokenserver-rs, handles authentication. When Firefox wants to sync, it first asks the tokenserver for a temporary token and the address of the storage node to use. The tokenserver checks your Firefox Account (FxA) identity and issues credentials.

Firefox Accounts itself is a third thing, and running your own FxA is a whole separate project that’s honestly more painful than most homelab setups. We’re not going down that road today.

The good news: you don’t have to. You can run self-hosted sync storage while still authenticating against Mozilla’s Firefox Accounts. Your FxA login still happens with Mozilla, which means your encryption keys are still derived from your Mozilla account credentials, but your sync data lands on your server, not Mozilla’s.

Is this a compromise? Sure. Mozilla still knows you logged in. But your bookmarks, history, and tabs stay local. For most people, that’s the meaningful win.


Setting It Up: syncstorage-rs + Docker Compose

You’ll need:

The Compose Stack

docker-compose.yml
version: "3.9"
services:
syncstorage:
image: ghcr.io/mozilla-services/syncstorage-rs:latest
restart: unless-stopped
depends_on:
- db
environment:
SYNC_HOST: "0.0.0.0"
SYNC_PORT: "8000"
SYNC_DATABASE_URL: "postgresql://syncuser:changeme@db:5432/syncdb"
# Shared secret used to validate tokens from Mozilla's tokenserver
SYNC_MASTER_SECRET: "your-very-long-random-secret-here"
SYNC_TOKENSERVER_URL: "https://token.services.mozilla.com/1.0/sync/1.5"
SYNC_HUMAN_READABLE_LOG: "true"
ports:
- "8000:8000"
db:
image: postgres:16-alpine
restart: unless-stopped
environment:
POSTGRES_USER: syncuser
POSTGRES_PASSWORD: changeme
POSTGRES_DB: syncdb
volumes:
- pgdata:/var/lib/postgresql/data
volumes:
pgdata:

A few things to understand about this setup:

Run It

Terminal window
docker compose up -d
docker compose logs -f syncstorage

Look for something like Listening on 0.0.0.0:8000 in the logs. If you see database connection errors, check your Postgres credentials and make sure the DB is actually up before the sync container starts (the depends_on helps but doesn’t guarantee readiness, add a healthcheck if you’re being thorough).

Reverse Proxy

Put this behind HTTPS. Here’s a minimal Caddyfile entry (Caddy being the sane choice for home setups):

sync.example.com {
reverse_proxy syncstorage:8000
}

Replace sync.example.com with your actual domain. Make sure it’s externally accessible, Firefox’s sync client will be connecting to it from wherever your devices are.


Pointing Firefox at Your Server

This is the part that feels illegal but is completely supported. Open a new tab, type about:config, and agree to be careful.

Search for:

identity.sync.tokenserver.uri

The default value is https://token.services.mozilla.com/1.0/sync/1.5.

Change it to:

https://sync.example.com/1.0/sync/1.5

Substitute your actual domain. This is telling Firefox: “when you need to sync, ask this tokenserver for the storage endpoint.” Since you’re running the storage server (not the tokenserver), you need to make sure your storage server responds correctly at that path.

Wait, this is the tricky bit. syncstorage-rs also implements a tokenserver-compatible endpoint, which means it can handle the /1.0/sync/1.5 path itself in “shared mode.” When Firefox hits your URL, your syncstorage-rs responds with its own node URL pointing back to itself. The shared secret you set ties it together.

Sign out of Firefox Sync, then sign back in. Watch about:sync-log (type it in the address bar), you should see sync events and, crucially, your domain name appearing in the connection logs instead of Mozilla’s servers.

If you see errors in the sync log, the most common culprits are:

  1. HTTPS cert issues (self-signed certs will fail silently)
  2. The tokenserver URI not matching exactly what the server expects
  3. Firewall blocking port 443 to your domain

The Retention Question

One underrated advantage of self-hosting: you control history retention. Mozilla’s sync server prunes old records according to their own schedule. Your server, your rules.

That said, syncstorage-rs doesn’t expose a simple “keep history for X days” config. You’d manage this at the database level, a periodic SQL job or cron that prunes the bso table by modified timestamp. Not hard, but not automatic either.

-- Prune sync records older than 90 days
DELETE FROM bso
WHERE modified < EXTRACT(EPOCH FROM NOW() - INTERVAL '90 days');

Wrap that in a cron or a scheduled Docker task and you’ve got custom retention. Mozilla can’t do that for you.


Risks You Should Actually Think About

Here’s the part where we don’t pretend this is a perfect solution.

Mozilla can change the FxA API anytime. If Mozilla updates how Firefox Accounts issues tokens or changes the expected API shape, your self-hosted storage server might stop working until syncstorage-rs is updated. The project has historically lagged behind Mozilla’s production changes by weeks to months.

No official support. This is community-maintained self-hosting. If it breaks, you’re reading GitHub issues at 11 PM.

The “hybrid” setup is philosophically weird. You’re trusting Mozilla for auth but not for storage. If that bothers you, the alternative is running your own Firefox Accounts server, which is a production-grade multi-service deployment that makes this whole thing look simple by comparison. Most home labbers shouldn’t touch it.

Updates require attention. ghcr.io/mozilla-services/syncstorage-rs:latest will pull whatever’s current, which could break things. Pin to a specific tag in production, and check the GitHub releases page before updating.


Alternatives Worth Knowing

If the Mozilla-FxA dependency bothers you, you have options:

xBrowserSync, genuinely self-hostable with no external auth dependency. Works across Chrome, Firefox, and Edge. Feature set is lighter (bookmarks and notes only, no history or passwords), but the self-hosting story is clean. Worth it if bookmarks are all you care about.

Floccus + Nextcloud Bookmarks, if you’re already running Nextcloud, this is probably the path of least resistance. Browser extension syncs bookmarks to your Nextcloud instance. History and passwords aren’t in scope, but it’s dead simple.

Vaultwarden, if passwords are your main concern, Vaultwarden (Bitwarden-compatible server) is the obvious answer. More mature, more actively maintained, and password management is its whole job.

None of these are full Firefox Sync replacements. They’re tradeoffs. Know what you actually want to protect before you pick.


Should You Bother?

Honestly? It depends on your threat model and your patience budget.

Run self-hosted Firefox Sync if:

Don’t bother if:

The client-side encryption story is actually pretty good. Mozilla’s sync servers hold encrypted blobs they can’t read. The main thing self-hosting buys you is removing Mozilla as a metadata holder (who synced when, device counts, sync frequency) and giving you control over retention and availability.

That’s real value, just be honest about what you’re getting into. It’s a working solution in 2026, it’s not as polished as Mozilla’s hosted version, and it will occasionally require your attention when upstream changes. If that sounds like your kind of weekend project, fire up the compose file and go for it. Your future self will either be proud of the setup or quietly switching back to Mozilla’s servers after a particularly annoying upstream break, and that’s fine either way.

The code is real, the setup works, and the choice is yours.


Share this post on:

Send a Webmention

Written about this post on your own site? Send a webmention and it'll show up above once verified.


Previous Post
Wezterm vs Alacritty vs Kitty: Modern Terminals
Next Post
Memos: Self-Hosted Microblog Meets Daily Note

Discussion

Powered by Garrul . Sign in with GitHub or Google, or post anonymously.

Related Posts