Syncing your chats
Your conversation history lives on the device where the chat happened. Syncing gives it somewhere to meet: a folder or a storage bucket you own, which every device you sign in on reads and writes.
Nothing goes to our servers, and whatever holds the files can't read them. They arrive already encrypted, under a key only your passkey derives.
Turn it on in Settings → Storage → Sync your chats.
What syncing does
- Carries conversations and messages, including their attachments and generated images, between every device signed in to your account.
- Runs continuously. A change reaches the target within about a second, and each device checks for other devices' changes every minute — plus whenever you come back to the tab.
- Merges rather than overwrites. Two devices editing different things in the same conversation both keep their edit; a rename on one and a new message on the other don't fight.
What it deliberately leaves out:
| Not synced | Why |
|---|---|
| Settings | Theme, session timeout, and routing preferences are per-device on purpose. |
| Payment records | Your tickets are on-chain facts, not chat content. |
| Search index | Rebuilt locally on each device from the chats it has. |
Syncing is not a backup. It's a shared current state — delete a conversation on one device and it goes from all of them. For a copy that stands still, use Back up chats in the same settings pane.
Pick where it syncs
Two options, and they're a choice, not a fallback — pick the one that fits your devices.
| A folder on this computer | A storage bucket | |
|---|---|---|
| Where it works | Desktop Chrome, Edge, Brave, or another Chromium browser | Every browser, phones included |
| What you provide | A folder something already syncs — Dropbox, Google Drive, iCloud Drive, OneDrive, Syncthing | An S3-compatible bucket you own |
| Setup | Point at the folder | Endpoint, bucket, keys, and a CORS rule |
| Other companies involved | Whoever runs the sync app | Whoever runs the bucket — or nobody, if you host it |
Switching between them is stop, then connect again. Files already written stay where they are.
Sync through a folder
Choose the folder option
In Settings → Storage → Sync your chats, pick A folder on this computer.
If your browser can't do this, the app says so rather than hiding the option.
On Brave, folder access is behind a flag — the app gives you the
brave://flags switch to turn on. On Safari, Firefox, and every phone
browser, use a bucket instead.
Point it at a synced folder
Your browser asks which folder, and asks permission to write to it. Choose a folder your sync app already watches — the Dropbox folder, an iCloud Drive folder, a Syncthing share.
Anything works, including a plain folder on a USB stick, but a folder nothing syncs only ever holds one device's chats.
Repeat on your other computers
Point each one at the same synced folder. They find each other through it.
Browsers drop folder permission when they restart, so you'll occasionally see Reconnect in the settings pane. One click, and it picks up where it was.
Sync through a bucket
A bucket works everywhere a browser does — this is the option that reaches your phone.
Create a bucket
Make a dedicated bucket for this, at any S3-compatible provider. The app knows six:
| Provider | Notes | |
|---|---|---|
| Someone hosts it | Filebase | Create it as an S3 bucket, not an IPFS one — objects in an IPFS bucket stay fetchable by CID from public gateways, and unpinning is not a guaranteed delete. |
| Cloudflare R2 | Endpoint is https://<account-id>.r2.cloudflarestorage.com; region stays auto. | |
| Amazon S3 | Leave Block Public Access on. The keys need list on the bucket and get/put/delete on its objects. | |
| You host it | Garage | S3 port 3900, and it serves no TLS itself — put a reverse proxy in front. The region comes from s3_region in garage.toml. |
| SeaweedFS | S3 port 8333. Region is us-east-1 unless you configured one. | |
| Something else | Other S3-compatible | Anything that speaks S3, MinIO included. |
Two rules whatever you choose:
- Never turn on object versioning, or any retention or undelete feature. A version history quietly keeps the copy you asked to be rid of.
- Give it its own bucket. The app owns the layout inside it.
Allow this app to reach it
A browser won't talk to a bucket that doesn't invite it, so the bucket needs a CORS rule. The app shows you the exact policy to paste under How to set this up, and offers to narrow it to this app's address:
[
{
"AllowedOrigins": ["*"],
"AllowedMethods": ["GET", "PUT", "DELETE", "HEAD"],
"AllowedHeaders": ["*"],
"ExposeHeaders": ["ETag"],
"MaxAgeSeconds": 3600
}
]
"*" is safe here: what authorizes a request is its signature, not where it
came from, and no cookie is involved.
On Filebase this is the CORS tab's Public Read-Write preset —
Read-Only is not enough. Elsewhere it's a bucket setting, or one
put-bucket-cors call.
Fill in the form
Pick your provider, then give the app the endpoint (the host only — the bucket goes in its own field), the bucket name, the region, and an access key and secret. There's an optional folder inside the bucket, which lets one bucket hold more than one account's chats.
Test it
Test connection runs four checks — list the bucket, write a test object, read it back, delete it — and tells you which one failed and what to change. Connect bucket runs the same four and saves nothing unless all four pass.
Your secret key is stored in this browser, encrypted under your account's passkey. Anyone who can use this browser while you're signed in can use the bucket.
Add another device
Once a bucket is connected, you don't retype any of that on the next device.
Reveal the connection string
On the device that's already syncing, open Settings → Storage and choose
Reveal — requires your passkey. Your passkey confirms it's you, and a QR
code and a zsmirror1: string appear.
The reveal hides itself again after 90 seconds. Showing it again costs another passkey prompt.
Carry it across
Scan the QR code with the new device's camera — it opens a setup page directly, so there's no app to install and no camera permission to grant.
Or press Copy string and paste it into the Paste a connection string field at the top of the bucket form on the other device. It fills in everything.
Connect
The new device shows you which bucket it's about to join, asks you to sign in with your passkey, and runs the same four checks. Then your chats arrive.
The connection string carries the bucket's keys. Anyone who has it can read and write your bucket — treat it the way you'd treat the secret key itself. Don't post it, and don't leave the QR code on screen.
The part of the scanned link that carries the settings is never sent to a server, and the app clears it from the address bar before doing anything else.
What the storage can see
Everything written is sealed on your device first, with a key derived from your passkey — the same passkey on another device derives the same key, which is why there's no passphrase to invent or transfer.
So whoever holds the folder or bucket sees ciphertext and shape: how many files there are, how big they are, when they changed, and how many devices you sync from. Never a title, a message, or who you talked to. It's the same exposure your Dropbox folder already has for everything else in it.
That also means the storage provider cannot help you read your chats, and neither can we. If you lose your passkey, the files are recovered through your recovery phrase, not through the bucket.
Deleting
Deleting a conversation deletes it everywhere — that's the point of syncing, and it's treated as a privacy action rather than an edit. A delete wins over any change made elsewhere, including a later one, and there is no state in which a deleted chat comes back.
One exception worth knowing: if you delete a chat while a device is disconnected from syncing, and then connect it to a fresh target, that chat can reappear. Delete it again and it goes for good. The alternative — carrying deletions across a target change — could wipe an archive irreversibly, so the app errs toward the recoverable mistake.
When syncing pauses
Chat keeps working regardless; only the copying stops. The settings pane names what's wrong:
| What it says | What to do |
|---|---|
| Another tab is handling the sync | Exactly one tab drives the target. Close the other one, or use it instead. |
| Needs your permission again | Folders lose access when the browser restarts. Press Reconnect. |
| The folder isn't reachable | A disconnected drive, or a sync app that isn't running. |
| The browser refused to send the request | Almost always the bucket's CORS rule. Re-paste the policy from How to set this up. |
| The bucket is refusing these credentials | The keys were revoked or narrowed. Generate new ones. |
| This device's clock is off | Signed requests are rejected for a clock more than 15 minutes out. Fix the clock; your keys are fine. |
| Out of space | Free some up on the drive or in the bucket. |
Check now forces a pass, and Verify bucket / Verify folder does a full comparison rather than the quick check.
What's next
- Conversations & history — the sidebar, search, and compacting.
- Settings — backup and restore, which live alongside syncing.
- Privacy & security — what each party in the system can see.