Skip to main content

Overview

Sync is the process of keeping local data consistent with the server. Zeus uses a local-first approach where changes are made locally first, then synchronized in the background.

How Sync Works

The Sync Cycle

  1. Local Change - User creates/updates/deletes an entity
  2. Queue for Sync - Entity marked with syncStatus
  3. Background Sync - App attempts to sync when online
  4. Server Update - Server processes the change
  5. Confirmation - Local entity updated with serverId and synced status

Sync Status Lifecycle

Sync States

synced

The entity is in sync with the server. No action needed.

pending_create

A new entity that hasn’t been created on the server yet.

pending_update

An existing entity that has been modified locally and needs to update the server.

pending_delete

An entity marked for deletion. Will be hard-deleted after server confirmation.

Triggering Sync

Automatic Sync

Sync runs automatically on app startup:
// In bootstrap.dart
await cache.initializeSync();

Manual Sync

Trigger sync manually:
final result = await cache.sync();

if (result.success) {
  print('All changes synced!');
} else {
  print('Sync failed: ${result.error}');
}

Listening to Progress

cache.syncProgress?.listen((progress) {
  print('${progress.step}: ${progress.percent}%');
  print('Items: ${progress.processedItems}/${progress.totalItems}');
});

Sync Order

Entities sync in dependency order:
  1. Categories - No dependencies
  2. Wallets - No dependencies
  3. Transactions - Depends on wallets and categories
This ensures foreign key references are valid when transactions sync.

Conflict Resolution

Last-Write-Wins

When the same entity is modified on multiple devices:
  1. Server compares updated_at timestamps
  2. Latest change wins
  3. Outdated clients receive the current state on next sync

Example Scenario

Handling Failures

Retry Logic

Failed operations are automatically retried:
  1. Immediate retry on transient errors (network timeout)
  2. Exponential backoff for persistent errors
  3. Queue preserved across app restarts
  4. User can trigger manual retry

Error Types

ErrorHandling
Network timeoutRetry immediately
Server error (5xx)Retry with backoff
Validation error (4xx)Log error, skip retry
Authentication errorPause sync, re-auth

Offline Behavior

What Works Offline

  • ✅ Creating wallets, categories, transactions
  • ✅ Reading all cached data
  • ✅ Updating existing entities
  • ✅ Deleting entities (soft delete)

What Requires Connection

  • ❌ Initial data fetch (first install)
  • ❌ Syncing pending changes
  • ❌ Multi-device consistency

Best Practices

  1. Always handle sync failures gracefully - Don’t block UI
  2. Show sync status - Users should know if data is pending
  3. Respect user bandwidth - Batch sync operations
  4. Test offline scenarios - Ensure app works without network

Monitoring Sync

Track these metrics:
  • Pending operations count
  • Sync success rate
  • Average sync latency
  • Conflict frequency