Back to Super Productivity

SuperSync vs File-Based Sync Comparison

docs/sync-and-op-log/diagrams/07-supersync-vs-file-based.md

18.4.414.3 KB
Original Source

SuperSync vs File-Based Sync Comparison

Last Updated: January 2026 Status: Implemented

This document compares the two sync provider architectures: SuperSync (server-based) and File-Based (WebDAV/Dropbox/LocalFile).

Side-by-Side Architecture

mermaid
graph TB
    subgraph Title[" "]
        direction LR
        T1["<b>SUPERSYNC</b>
Server-Based"]
        T2["<b>FILE-BASED</b>
File-Based"]
    end

    subgraph SS["SuperSync Architecture"]
        direction TB

        SS_Client["CLIENT"]
        SS_Upload["Upload: POST /ops
━━━━━━━━━━━━━━━
Send ops array
Server assigns seq"]
        SS_Download["Download: GET /ops
━━━━━━━━━━━━━━━
Query since lastSeq
Returns only new ops"]
        SS_Server["SERVER
━━━━━━━━━━━━━━━
Validates sequence
Detects gaps
Returns 409 on conflict"]
        SS_DB[("PostgreSQL
━━━━━━━━━━━━━━━
operations table
All ops forever
Server-assigned seq")]

        SS_Client --> SS_Upload
        SS_Client --> SS_Download
        SS_Upload --> SS_Server
        SS_Download --> SS_Server
        SS_Server --> SS_DB
    end

    subgraph FB["File-Based Architecture"]
        direction TB

        FB_Client["CLIENT"]
        FB_Upload["Upload: uploadFile()
━━━━━━━━━━━━━━━
Download first
Merge + increment ver
Upload entire file"]
        FB_Download["Download: downloadFile()
━━━━━━━━━━━━━━━
Get entire file
Filter ops locally
Detect version changes"]
        FB_Provider["FILE PROVIDER
━━━━━━━━━━━━━━━
WebDAV/Dropbox/Local
Simple file operations
No server logic"]
        FB_File[("sync-data.json
━━━━━━━━━━━━━━━
Full state snapshot
Last 200 ops
Client-managed ver")]

        FB_Client --> FB_Upload
        FB_Client --> FB_Download
        FB_Upload --> FB_Provider
        FB_Download --> FB_Provider
        FB_Provider --> FB_File
    end

    style SS fill:#e3f2fd,stroke:#1565c0,stroke-width:3px
    style FB fill:#fff3e0,stroke:#e65100,stroke-width:3px
    style SS_DB fill:#c8e6c9,stroke:#2e7d32,stroke-width:2px
    style FB_File fill:#ffe0b2,stroke:#e65100,stroke-width:2px
    style Title fill:none,stroke:none

Key Conceptual Differences

mermaid
graph LR
    subgraph Concept["KEY DIFFERENCE"]
        direction TB
        C1["Where is the
<b>source of truth</b>?"]
        C2["Who manages
<b>sequence numbers</b>?"]
        C3["How are
<b>conflicts detected</b>?"]
        C4["What gets
<b>transferred</b>?"]
        C5["How do
<b>late joiners</b> sync?"]
    end

    subgraph SSAnswer["SuperSync"]
        direction TB
        A1["Server's PostgreSQL
database"]
        A2["Server assigns
serverSeq on insert"]
        A3["Server returns 409
with missing ops"]
        A4["Only the ops
that changed"]
        A5["Replay all ops
from server"]
    end

    subgraph FBAnswer["File-Based"]
        direction TB
        B1["The sync file
(sync-data.json)"]
        B2["Client increments
syncVersion locally"]
        B3["Client detects
version mismatch"]
        B4["Entire file
(state + ops)"]
        B5["Get state snapshot
from file"]
    end

    C1 --> A1
    C1 --> B1
    C2 --> A2
    C2 --> B2
    C3 --> A3
    C3 --> B3
    C4 --> A4
    C4 --> B4
    C5 --> A5
    C5 --> B5

    style Concept fill:#f5f5f5,stroke:#333,stroke-width:2px
    style SSAnswer fill:#e3f2fd,stroke:#1565c0,stroke-width:2px
    style FBAnswer fill:#fff3e0,stroke:#e65100,stroke-width:2px

Detailed Feature Comparison

AspectSuperSyncFile-BasedWinner
Bandwidth EfficiencyOnly transfers changed opsTransfers entire file each syncSuperSync
Setup ComplexityRequires account + serverUse existing cloud storageFile-Based
Offline DurationUnlimited (server stores all)Limited (only 200 ops retained)SuperSync
Self-HostingNeed to run serverJust need file storageFile-Based
Late Joiner SpeedSlow (replay all ops)Fast (load snapshot)File-Based
Conflict HandlingServer-authoritativeClient-side piggybackingTie
Real-time SyncYes (polling/webhooks)No (periodic sync)SuperSync
Data RecoveryFull op history availableLimited to snapshot + 200 opsSuperSync

Trade-offs Visualization

mermaid
graph TB
    subgraph Tradeoffs["TRADE-OFFS AT A GLANCE"]
        direction TB

        subgraph Bandwidth["Bandwidth"]
            SS_BW["SuperSync: ✅ LOW
Only delta ops transferred"]
            FB_BW["File-Based: ⚠️ HIGH
Full file each time"]
        end

        subgraph Setup["Setup Effort"]
            SS_Setup["SuperSync: ⚠️ HIGH
Account + server needed"]
            FB_Setup["File-Based: ✅ LOW
Use existing storage"]
        end

        subgraph History["Operation History"]
            SS_Hist["SuperSync: ✅ FULL
All ops stored forever"]
            FB_Hist["File-Based: ⚠️ LIMITED
Only last 200 ops"]
        end

        subgraph LateJoin["Late Joiner Experience"]
            SS_Late["SuperSync: ⚠️ SLOW
Must replay all ops"]
            FB_Late["File-Based: ✅ FAST
Just load snapshot"]
        end

        subgraph Complexity["Client Complexity"]
            SS_Comp["SuperSync: ✅ SIMPLE
Server handles sequences"]
            FB_Comp["File-Based: ⚠️ COMPLEX
Client manages versions"]
        end
    end

    style SS_BW fill:#c8e6c9,stroke:#2e7d32
    style FB_BW fill:#ffecb3,stroke:#ffa000
    style SS_Setup fill:#ffecb3,stroke:#ffa000
    style FB_Setup fill:#c8e6c9,stroke:#2e7d32
    style SS_Hist fill:#c8e6c9,stroke:#2e7d32
    style FB_Hist fill:#ffecb3,stroke:#ffa000
    style SS_Late fill:#ffecb3,stroke:#ffa000
    style FB_Late fill:#c8e6c9,stroke:#2e7d32
    style SS_Comp fill:#c8e6c9,stroke:#2e7d32
    style FB_Comp fill:#ffecb3,stroke:#ffa000

Concurrent Edit Scenario Comparison

mermaid
sequenceDiagram
    participant A as Client A
    participant B as Client B
    participant SS as SuperSync Server
    participant File as sync-data.json

    Note over A,File: ═══ SUPERSYNC: Server Detects Gap ═══

    rect rgb(227, 242, 253)
        A->>SS: POST /ops [op1, op2]
        SS->>SS: Assign seq 10, 11
        SS-->>A: OK {seqs: [10, 11]}

        B->>SS: POST /ops [op3] (lastKnown: 9)
        SS->>SS: Gap! Client missing 10, 11
        SS-->>B: 409 Conflict {missing: [op1, op2]}
        B->>B: Process missing ops first
        B->>SS: POST /ops [op3] (lastKnown: 11)
        SS-->>B: OK {seqs: [12]}
    end

    Note over A,File: ═══ FILE-BASED: Piggybacking ═══

    rect rgb(255, 243, 224)
        A->>File: Download (v=5)
        A->>A: Merge ops, set v=6
        A->>File: Upload (v=6)

        B->>File: Download (v=5, expects v=5)
        Note over B: Version changed! (now v=6)
        B->>B: Find A's ops in file (piggybacked)
        B->>B: Merge A's ops + own ops
        B->>B: Set v=7
        B->>File: Upload (v=7)
        B->>B: Process piggybacked ops locally
    end

Data Storage Comparison

mermaid
flowchart TB
    subgraph SuperSync["SuperSync Storage"]
        direction TB
        PG["PostgreSQL Database"]

        subgraph Tables["Tables"]
            OpsTable["operations
━━━━━━━━━━━━━━━
id, client_id, seq
action_type, payload
vector_clock, timestamp"]
            ClientsTable["clients
━━━━━━━━━━━━━━━
client_id, last_seq
created_at"]
        end

        PG --> Tables
    end

    subgraph FileBased["File-Based Storage"]
        direction TB
        SyncFile["sync-data.json"]

        subgraph Contents["Contents"]
            Meta["Metadata
━━━━━━━━━━━━━━━
version, syncVersion
lastModified, checksum"]
            State["State Snapshot
━━━━━━━━━━━━━━━
Full AppDataComplete"]
            Archive["Archive Data
━━━━━━━━━━━━━━━
archiveYoung, archiveOld"]
            RecentOps["Recent Ops (200)
━━━━━━━━━━━━━━━
CompactOperation[]"]
        end

        SyncFile --> Contents
    end

    style SuperSync fill:#e3f2fd,stroke:#1565c0,stroke-width:2px
    style FileBased fill:#fff3e0,stroke:#e65100,stroke-width:2px

Sync Flow Comparison

Download Flow

mermaid
sequenceDiagram
    participant Client
    participant SS as SuperSync Server
    participant FB as File Provider

    rect rgb(227, 242, 253)
        Note over Client,SS: SuperSync Download
        Client->>SS: GET /ops?since={lastSeq}
        SS->>SS: Query ops WHERE seq > lastSeq
        SS-->>Client: {ops: [...], lastSeq: N}
        Note over Client: Only receives new ops
Bandwidth efficient
    end

    rect rgb(255, 243, 224)
        Note over Client,FB: File-Based Download
        Client->>FB: downloadFile("sync-data.json")
        FB-->>Client: {state, recentOps, syncVersion}
        Client->>Client: Filter ops by lastProcessedSeq
        Note over Client: Downloads full file
Filters locally
    end

Upload Flow

mermaid
sequenceDiagram
    participant Client
    participant SS as SuperSync Server
    participant FB as File Provider

    rect rgb(227, 242, 253)
        Note over Client,SS: SuperSync Upload
        Client->>SS: POST /ops {ops: [...], lastKnownSeq}
        SS->>SS: Validate sequence continuity
        alt Gap detected
            SS-->>Client: 409 Conflict + missing ops
        else No gap
            SS->>SS: Insert ops, assign seq numbers
            SS-->>Client: 200 OK {assignedSeqs}
        end
    end

    rect rgb(255, 243, 224)
        Note over Client,FB: File-Based Upload
        Client->>FB: downloadFile (get current state)
        FB-->>Client: {syncVersion: N, recentOps}
        Client->>Client: Merge local ops + file ops
        Client->>Client: Find piggybacked ops
        Client->>Client: Set syncVersion = N+1
        Client->>FB: uploadFile(merged data)
        FB-->>Client: Success
        Note over Client: Returns piggybacked ops
for immediate processing
    end

Conflict Handling Comparison

mermaid
flowchart TB
    subgraph SuperSync["SuperSync Conflict Handling"]
        SS1["Client uploads ops"]
        SS2{"Server checks
sequence gap?"}
        SS3["Gap: Return 409
+ missing ops"]
        SS4["No gap: Accept ops"]
        SS5["Client downloads
missing ops"]
        SS6["LWW resolution
on client"]

        SS1 --> SS2
        SS2 -->|Yes| SS3
        SS2 -->|No| SS4
        SS3 --> SS5
        SS5 --> SS6
    end

    subgraph FileBased["File-Based Conflict Handling"]
        FB1["Client downloads file"]
        FB2{"syncVersion
changed?"}
        FB3["Version match:
Clean upload"]
        FB4["Version changed:
Piggybacking"]
        FB5["Merge all ops"]
        FB6["Upload merged file"]
        FB7["Return piggybacked ops"]
        FB8["LWW resolution
on client"]

        FB1 --> FB2
        FB2 -->|No| FB3
        FB2 -->|Yes| FB4
        FB4 --> FB5
        FB5 --> FB6
        FB6 --> FB7
        FB7 --> FB8
    end

    style SuperSync fill:#e3f2fd,stroke:#1565c0,stroke-width:2px
    style FileBased fill:#fff3e0,stroke:#e65100,stroke-width:2px

When to Use Each

mermaid
flowchart TD
    Start["Choose Sync Provider"] --> Q1{Need real-time
multi-device sync?}

    Q1 -->|Yes| Q2{Have SuperSync
account?}
    Q1 -->|No| FileBased

    Q2 -->|Yes| SuperSync
    Q2 -->|No| Q3{Have cloud
storage?}

    Q3 -->|WebDAV/Dropbox| FileBased
    Q3 -->|No| LocalFile

    SuperSync["SuperSync
━━━━━━━━━━━━━━━
• Real-time sync
• Efficient bandwidth
• Server-managed gaps
• Best for active teams"]

    FileBased["File-Based Sync
━━━━━━━━━━━━━━━
• Uses existing storage
• No additional account
• Self-hosted option
• Good for individuals"]

    LocalFile["Local File
━━━━━━━━━━━━━━━
• Manual sync
• Full control
• Backup purposes"]

    style SuperSync fill:#e3f2fd,stroke:#1565c0,stroke-width:2px
    style FileBased fill:#fff3e0,stroke:#e65100,stroke-width:2px
    style LocalFile fill:#e8f5e9,stroke:#2e7d32,stroke-width:2px

Implementation Details

Shared Infrastructure

Both providers implement OperationSyncCapable interface and use:

ComponentPurpose
OperationLogSyncServiceOrchestrates sync timing and triggers
ConflictResolutionServiceLWW resolution for concurrent edits
VectorClockServiceCausality tracking for all operations
OperationApplierServiceApplies remote ops to NgRx state
ArchiveOperationHandlerHandles archive side effects

Provider-Specific Components

SuperSyncFile-Based
SuperSyncProviderFileBasedSyncAdapter
REST API clientFile provider abstraction
Server-side sequence managementClient-side syncVersion tracking
Gap detection via HTTP 409Piggybacking on version mismatch

Key Files

FilePurpose
src/app/op-log/sync-providers/super-sync/SuperSync provider implementation
src/app/op-log/sync-providers/file-based/File-based adapter and types
src/app/op-log/sync/operation-log-sync.service.tsShared sync orchestration
src/app/op-log/sync/conflict-resolution.service.tsLWW conflict resolution