Sync issues
Cloud sync moves changes from each desktop device up to the cloud server, then back down to every other device. When it stalls, two devices show different totals; when it diverges, the FK resolver in the server log starts complaining; when it gets stuck, the last-synced timestamp doesn’t move forward. This page covers what’s happening and how to fix it without losing data.
How sync works (the short version)
The desktop pushes any record marked _isDirty to the cloud, then pulls anything the cloud has changed since the device’s last _lastSyncedAt. Conflicts are last-write-wins. A separate FK resolver stitches up foreign keys whose referenced rows haven’t arrived yet (e.g., a sale referencing a customer that’s still in the upload queue). Errors from the resolver land in the server log.
Find the log first
Server stderr logs hold every sync error and FK resolver warning:
- macOS —
~/Library/Application Support/com.minib2c.pos/server-stderr.log - Windows —
%APPDATA%\com.minib2c.pos\server-stderr.log - Linux —
~/.local/share/com.minib2c.pos/server-stderr.log
Search for [sync] and [fk-resolver] to filter. The most useful lines:
[sync] push: N records sent/[sync] pull: M records received— healthy.[sync] push failed: <reason>— server rejected an upload.[fk-resolver] orphan: <table>.<id> references missing <table>.<id>— a foreign key can’t resolve. Common during initial pull; concerning if it persists across passes.[sync] backoff: retrying in Ns— transient failure; sync will recover automatically.
Symptom-to-fix
Last-synced timestamp hasn’t moved in over an hour
First check — is the device online? Header badge says “Working offline” if it isn’t. See Connection issues if you expect to be online but aren’t.
Second check — is the cloud server reachable? Try https://<your-cloud-host>/api/health in a browser. If it doesn’t answer, the cloud is down (rare; check Dokploy / hosting status) or your network blocks outbound HTTPS to that domain.
Third check — Settings → System → Sync → Sync now. The button forces a push/pull cycle and surfaces the actual error in a toast. If it still doesn’t move, look at the log.
Two devices show different totals
Cause — one of the devices hasn’t pulled the other’s changes yet. Common when device A rang sales while device B was offline.
Confirm both devices are online
Both should show no “Working offline” badge.
Force a sync on each
Settings → System → Sync → Sync now on both devices, in any order.
Re-check the totals
Within 30 seconds the numbers should match. If they don’t, one device has data the other can’t reconcile — proceed to the force re-pull workflow on the outdated device.
”Last synced” jumps forward but data didn’t change
Cause — push succeeded, but the pull side returned an empty changeset because the cloud doesn’t have anything newer than this device. That’s healthy if you’re the only active device; concerning if other devices were ringing sales.
Check the other device’s _lastSyncedAt. If it’s older than yours, that device hasn’t pushed yet. Open it and force sync.
FK resolver complaints in the log
Cause — a record references another record that hasn’t synced yet. The resolver retries each pass; most warnings clear within a few minutes.
When to worry — if the same FK warning persists across many sync passes (an hour or more), the referenced row is genuinely missing, usually because:
- It was deleted on one device while still being written on another.
- A snapshot restore reverted one side without the other.
- A migration was applied unevenly.
Fix — Settings → System → Sync → Repair foreign keys. The button runs the resolver in repair mode, which inserts placeholder rows for genuinely-missing references and surfaces the affected records for review. Don’t run repair mode unless the warnings are persistent — it’s noisier than the automatic resolver.
Snapshot restore mismatches with cloud state
You restored a snapshot on a desktop device. Now this device has data the cloud has never seen, and the cloud has data this device doesn’t have. The next sync push tries to send the restored data, and the next pull tries to apply cloud changes on top.
The safe path: restore the snapshot, then force a re-pull from cloud so the device matches the cloud exactly. You’ll lose any local changes made in the brief window between restore and re-pull, but you keep the cloud’s authoritative state.
Force re-pull
This wipes the local SQLite database and re-pulls everything from the cloud. Use it as a last resort when a single device is so out of sync that incremental fixes won’t catch up.
Push everything you can
Settings → System → Sync → Sync now. Wait until the badge clears or stops moving. Read the log: any record that genuinely can’t push is going to be lost in the next steps.
Take a manual snapshot
Settings → System → Backup → Create snapshot now. This is your only undo if step 4 is the wrong choice.
Quit Fexl Lite completely
All windows closed, tray icon gone.
Run force re-pull
Relaunch with the Force re-pull flag from the launcher menu (Help → Sync → Force re-pull from cloud). The app deletes retail.db, creates a fresh empty DB, and pulls every tenant record from cloud. On a tenant with 50K records and a healthy connection, this takes 1–3 minutes; on a slow connection it can take 10+.
Verify totals
Cross-check today’s revenue, last week’s revenue, and the customer count against another known-good device or the cloud admin UI.
Cloud-mode failover and re-sync
When cloud sync is enabled, the API client hits cloud first and falls back to the local server only on network failure. While offline, sales are written locally and queued. When connectivity returns, the queue drains automatically — you should see the “Working offline” badge clear within 30 seconds of being back online, then a flurry of sync activity in the log.
If the queue doesn’t drain after the device is clearly online, force sync from Settings. If that doesn’t work, look for FK resolver complaints in the log — sometimes a queued record references a customer or product that was deleted on another device while you were offline.
Things that aren’t a sync issue
- Numbers in a single report look wrong, but two devices agree — that’s a report bug, not sync. The numbers are wrong everywhere consistently. File a ticket.
- One specific invoice is missing on one device — could be sync, but if it’s been more than an hour and a force-sync doesn’t pull it, the invoice may have been hard-deleted (rare). Check the audit log on the cloud.
- Slow login with the spinner stuck — that’s Connection issues, not sync. Sync runs after login.
Still stuck?
- Open a support ticket with: (a)
_lastSyncedAtfrom each affected device, (b) the last 100 lines ofserver-stderr.logfrom the slowest-syncing device, (c) whether you’ve run force re-pull, (d) any FK resolver warnings you’ve seen. - If the cloud server itself is the issue (multiple tenants affected), support will see it in their dashboard before you finish writing the ticket. Mention if other tenants in your network are also reporting problems.
Related
- Cloud sync architecture — how the worker, queue, and FK resolver fit together
- Settings → System → Sync — the panel that owns Sync now, force re-pull, and FK repair
- Connection issues — when the device can’t reach the cloud at all
- Login & PIN — when the user list itself looks wrong (often a sync issue under another name)