LOG-SYN-002

Sync Engine

Issue Date6/15/2024
VerificationProduction Ready
#OfflineFirst#DistributedSystems#LWW
Ledger Directory / Core Architecture

Designing a Resilient Offline-First Synchronization Engine

In modern system design, treating the local database merely as a cache of the cloud state is a common architectural anti-pattern. When an application must remain fully functional during extended network partitions—such as in mobile deployments, field operations, or desktop software—the client must be treated as a primary source of truth. The local database is where user writes occur, while the cloud backend acts as a transactional synchronization and distribution layer across replicas.

Building a client-authoritative, offline-first database engine introduces severe distributed-system complexities:

  • State Machine Explosion: Tracking dirty or modified states across dozens of independent database tables results in massive metadata pollution and fragile repository logic.
  • Loss of Client Intent: Pulling remote changes while local modifications are still pending can cause silent, destructive overwrites of the user’s unpushed offline edits.
  • Write Amplification & Resource Exhaustion: Naive client-side batch pushes can overload backend databases, driving up cloud transaction fees and increasing the risk of Economic Denial of Service (EDoS).
  • Silent Resurrections: Failing to model deletions explicitly can cause deleted records to reappear when late-syncing replicas reconnect.

This manifesto details the design of a resilient, policy-driven offline-first synchronization engine. By focusing on system threat models (risks) and structural design boundaries (guardrails), this architecture ensures deterministic state convergence across decentralized replicas without requiring distributed locks or complex coordination protocols.


1. The Client-As-Origin Paradigm

Traditional synchronization systems rely on a pull-then-push flow. Under intermittent connectivity, this flow is inherently fragile because it forces the client to merge incoming remote changes before it has had a chance to preserve its own offline intent on the server.

To guarantee data safety, this engine enforces a strict push-before-pull execution sequence:

Execution Pipeline

Push Before Pull Sequence

Deterministic Safety Gate
Phase 01
Upload Pending Intent

The client uploads its local persistent Mutation Queue in chunked batches. Stale, redundant changes are dropped at the gateway in-memory.

Active Queue Isolation
Phase 02
Download Cloud State

Once push receipts are completed, the client pulls the consolidated canonical state. This guarantees local changes are not overwritten.

Awaiting Push ACK
Phase 03
Converge and Apply

The client database applies remote updates. If a local mutation was queued during pull, the write barrier skips the update for safety.

State Converged

The client first pushes its pending offline changes to the central gateway. Once those mutations are recorded and acknowledged by the server, the client pulls the consolidated canonical state from the cloud. This order ensures that local changes are represented upstream before remote updates are permitted to influence local state.


2. The Paradigm Shift: Pull-Merge-Push vs. Push-then-Pull

To appreciate why the synchronization engine is structured around a Push-then-Pull sequence, we must analyze the severe distributed systems failures of the traditional Pull-Merge-Push model.

Traditional PatternPull Merge Push

Client-Side Differential Merge

Forces mobile and edge devices to reconcile multiple conflicting replicas locally before they are permitted to upload.

  • Shadow Tables Required

    Requires storing duplicates of all tables to calculate client vs. server changes, doubling local database footprint.

  • Concurrency Race Conditions

    Active UI writes running alongside background merge computations frequently lock database threads and corrupt state.

  • Blind Production Diagnostics

    Conflict calculation is scattered across thousands of client devices, leaving no server trace of broken states.

Performance Cost: HighStorage Overhead: 200%
Kanz StandardPush Then Pull

Chronological Transaction Stream

Treats client writes as a simple, append-only log of intent. Authoritative conflict resolution is offloaded entirely to the gateway.

  • Zero Shadow Tables

    No duplicate database tables or diff calculation logic needed on the device, saving flash storage lifecycle and memory.

  • No Client Concurrency Merges

    The client simply flushes its queue and downloads the clean server-resolved state. UI database queries stay fast and non-blocking.

  • Authoritative Server-Side Audit

    Conflict decisions are resolved at the gateway, leaving a centralized, immutable access log for instant troubleshooting.

Performance Cost: MinimalStorage Overhead: 0%

The Threat: The Client-Side Differential Merge Burden (Pull-Merge-Push)

In a Pull-Merge-Push architecture, the client must pull remote server changes before it is allowed to upload its own. This forces the client to resolve state differences locally.

This model introduces three critical systemic risks:

  1. The Shadow Table Requirement (Storage Bloat): To calculate a clean merge without losing user data, the client-side database cannot simply overwrite rows. It must run a client-side differential engine (such as a three-way merge). This requires storing shadow tables—duplicate copies of the local tables representing the exact state of the last successful pull—to calculate what changed locally versus what changed remotely. Shadow tables double local database size and dramatically increase disk write-amplification.
  2. Concurrency Race Conditions: While the client is locally computing a complex merge of a pulled dataset, the user is still interacting with the UI and writing new mutations. Resolving merges concurrently with active local writes frequently leads to race conditions, locked database threads, and silent cache corruption.
  3. Complex Client-Side Debugging: Merging multi-replica conflicts on a mobile or desktop client means conflict-resolution logic is distributed across thousands of untrusted, unmonitored devices. Debugging a corrupted merge state in production is nearly impossible because the server has no record of the intermediate state calculation.

The Guardrail: Chronological Transaction Streams (Push-then-Pull)

By reversing the order to a strict Push-then-Pull sequence, the engine completely offloads the complex merging logic from client memory:

  1. Elimination of Shadow Tables: Because the client pushes its pending chronological mutations first, it treats the local Mutation Queue as an isolated transaction log. The server—which is the only entity with a complete global view of all replicas—performs the authoritative conflict adjudication (using Last-Write-Wins and tombstone markers).
  2. Zero Client-Side Merge Calculation: The client never has to calculate differential merges. It simply uploads its intent, receives confirmation, and then pulls the canonical, reconciled state from the gateway. This keeps the client database entirely free of shadow tables, reduces disk writes, and eliminates merge-related memory overhead.
  3. Immutable Synchronization Auditing: Because all conflict adjudication occurs at the gateway, the server maintains an immutable record of why a specific replica’s write won or was rejected. If a desynchronization event occurs, it can be diagnosed and resolved entirely through server-side access logs without needing to inspect raw client memory.

3. Threat Model 1: State Machine Explosion (The Change-Detection Problem)

  • The Risk (Polluted Domain Schemas): Traditional change-detection strategies rely on row-level “dirty flags” (such as is_dirty, pending_insert, pending_delete) embedded directly inside every business database table. When a user performs multiple rapid offline operations on the same row (e.g., creating a record, updating it three times, then deleting it), repositories must manage a complex, branch-heavy state machine to reconcile those changes. This tightly couples synchronization logic to the local database schema, creating a high risk of data corruption.
  • The Guardrail (Operation Logging): Instead of detecting modifications after they occur, the database layer must record mutations in an isolated, persistent Mutation Queue at the exact millisecond they happen. The business database tables remain clean of synchronization metadata.
System Isolation Blueprint

Database Schema Segregation

LOG-SYN-DB
Business Tables
domain database.sqlite
Records TableID | Name | Data | UpdatedAt
Collections TableID | Name | TenantId
Users TableID | Email | Settings

Zero synchronization metadata dirty flags or state columns inside your core business logic schemas.

Isolated Log
Write On Mutation
Mutation Queue
sync mutation_queue.sqlite
EntryIdUUID (Primary Key)
EntityTypeTEXT (e.g. "Record")
EntityIdUUID
OperationENUM
PayloadJSON (Snapshot)

By keeping the queue segregated from the business tables, the synchronization engine operates on a single, uniform data model regardless of the entity type.

Bounded Queue Growth via Identity Collapsing

To prevent the queue from growing indefinitely during long offline sessions, the Mutation Queue enforces a composite primary key of (entityType, entityId). Only one pending operation per entity can exist in the queue at any time.

When a user edits the same record multiple times while offline, the queue collapses intermediate mutations:

INSERT
UPDATE
UPDATE
Identity Collapse
Queue State
UPSERT (Latest Snapshot)

This ensures that the queue’s size remains proportional to the number of edited entities, rather than the number of edits performed, keeping memory and network footprints bounded during reconnection.


4. Threat Model 2: Loss of Client Intent during Pull (The Local Overwrite Problem)

  • The Risk: During the pull phase, the client downloads updated records from the central server. If the user edited a record locally while offline, and the sync engine immediately applies an incoming server-side update for that same record, the client’s unpushed offline changes will be silently overwritten and permanently lost.
  • The Guardrail (The Local Write Isolation Barrier): Before applying any remote record downloaded during the pull phase, the client-side engine must perform a pre-flight check against the Mutation Queue.

If a pending mutation exists in the local queue for that specific (entityType, entityId) pair, the incoming remote update is skipped. The local database remains authoritative until the pending mutation is successfully pushed and acknowledged.


5. Threat Model 3: Write Amplification & Quota Exhaustion (The Infrastructure-Load Problem)

  • The Risk: In decentralized synchronization systems, write amplification can quickly exhaust database quotas and run up substantial cloud infrastructure bills (EDoS). If clients perform raw database writes directly to cloud collections, the server cannot validate state consistency or reject stale writes efficiently, leading to massive redundant operations.
  • The Guardrail (Gateway-Level Write Adjudication): All outgoing mutations must route through a stateless validation gateway before hitting the cloud database.
Gateway Adjudication Pipeline

Authoritative Server Resolution

Write Optimization
1. Batch Ingestion

Mutations arrive in batches of 50. Offloads connection handshake overhead and handles bulk network processing cleanly.

2. Bulk Validation

Performs bulk read queries to fetch the current server state of all incoming records in a single database round-trip.

3. RAM Diffing

Compares incoming timestamps in-memory. If the write is older than or equal to the server record, it is immediately dropped.

4. Idempotent ACK

Returns an explicit list of processed IDs. Client clears only confirmed records, ensuring safe retries on network drop.

The gateway performs four key optimization steps:

  1. Batch Ingestion: Client mutations are pushed in bounded batches (e.g., 50 records) to minimize network handshake overhead.
  2. Bulk Validation: The gateway performs bulk read queries to fetch the current cloud state of all incoming IDs in a single database round-trip ($O(1)$ database reads).
  3. In-Memory Adjudication (RAM Diffing): Incoming payloads are compared with current server state in memory. If the incoming mutation’s timestamp (updatedAt) is older than or identical to the server’s record, the write is dropped.
  4. Idempotent Acknowledgment: The gateway processes the batch and returns an explicit list of processed IDs. The client removes only the acknowledged entries from its local Mutation Queue, ensuring that unacknowledged writes are retried safely.

6. Threat Model 4: Ghost Records & Silent Resurrections (The Deletion Problem)

  • The Risk: In standard databases, deleting a record removes it from the disk. However, in an offline-first system, simply removing a local row is catastrophic. Other synchronized client replicas will have no record of the deletion and will treat the record as “missing” on the server, causing them to silently upload and resurrect the deleted record during their next pull cycle.
  • The Guardrail (Monotonic Tombstones): Deletions are treated as first-class, monotonic state changes. When a record is deleted, the system writes an explicit tombstone entry containing the record’s unique ID and the deletion timestamp.

This tombstone competes directly in the conflict resolution timeline:

  • If a client attempts to push an offline update with a timestamp older than the deletion tombstone, the server rejects the update.
  • If the client attempts to push an update newer than the tombstone, the record is safely resurrected with the updated state.

7. The Architectural Evolution

This synchronization architecture has evolved through several iterations to meet operational demands, shifting from simple client-driven replication to an environment-safe, policy-driven boundary:

Evolution Ledger

Sync Engine Phases

System Lifecycle
01
Pure Replay (Phase 1)

Established foundational operation queueing, monotonic delete tombstones, and the client-first push before pull transaction stream.

02
Policy Gating & API Segregation (Phase 2)

Segregated database operations into Recording (app-facing) and Processing (sync-engine facing) contracts. Introduced decoupled execution policies.

03
Sync Status Reports (Phase 3 - Active Standard)

Unified policy validation and queue state analysis into a single pre-flight diagnostic report, allowing workflows to dynamically assess execution safety.

Phase 1: Client-Driven Replay (V1)

  • The Paradigm: The initial design proved the viability of operation queues, payload snapshots, and LWW-based tombstones.
  • The Problem: The synchronization process was tightly coupled to application state. The engine could not easily determine why sync was blocked (e.g., subscription limits vs. network drops), and repositories were exposed to low-level sync processing details.

Phase 2: Policy-Driven Gating & API Segregation (V2)

  • The Paradigm: The database interfaces were segregated into two strict contracts: the Recording API (used by local repositories to write mutations) and the Processing API (used only by the sync engine). This ensured that business repositories had no visibility into batch parsing or queue clearing.
  • The Problem: While APIs were clean, complex application workflows (such as account sign-out or initial hydration) had to duplicate logic to evaluate whether they could safely execute sync.

Phase 3: Pre-flight Status and Pre-sync State Awareness (V2.2)

  • The Paradigm: The modern stable standard introduces a unified Pre-flight Status Report. Before execution begins, the engine evaluates both runtime environment policies and current queue states, returning a single, immutable status report that answers both: “Can we sync?” and “Do we need to sync?”

8. Decoupled Operational Gating & Sync Policies

To prevent the engine from becoming coupled to application-level concerns (such as billing plans, user settings, or network connectivity profiles), execution is governed by a Policy Compositions Engine.

Instead of using scattered boolean conditionals, the sync engine evaluates a set of decoupled validation rules:

Trigger Evaluation
Evaluate SyncPolicy Compositions
Hard Gate
Abort Execution Immediately

Critical constraints that can never be overridden (e.g. Session expired, User logged out, Account suspended).

Sync Halts
Soft Gate
Evaluate force Flag

Environmental restrictions or preferences (e.g. cellular data restriction, low battery, user disabled auto-sync).

Force Bypass Allowed
All Gates Clear
Execute Synchronize

All system policies validate successfully. Sync engine initializes connection channels and schedules database push tasks.

Sync Executing

Hard Gates vs. Soft Gates

The policy engine categorizes constraints into two distinct behaviors:

  1. Hard Gates: Enforce physical and legal boundaries of the system (e.g., authentication status, subscription verification). Hard gates ignore override requests and immediately abort synchronization.
  2. Soft Gates: Represent user preferences or environmental guidelines (e.g., “Sync only on Wi-Fi” or “Disable sync during low battery”). These gates can be bypassed using a force flag during critical system workflows (such as final account reconciliation before a sign-out) to preserve database integrity.

9. Engineering Tradeoffs

A highly reliable sync architecture requires explicitly documenting its chosen operational boundaries:

  • No Global Time Coordination: The system relies on client-generated timestamps for conflict resolution. This design choice trades absolute causal ordering for high local availability and extreme horizontal scalability. While extreme clock drift can result in ordering conflicts, this is accepted as a standard tradeoff for local authority.
  • No Semantic Merging: Conflicts are resolved entirely through Last-Write-Wins (LWW) at the record level. The engine does not attempt to perform collaborative text merges or field-level CRDT reconciliation, keeping local database updates highly performant and deterministic.
  • Replication vs. Event Audit: The Mutation Queue tracks the latest intended replication state, not a complete, permanent audit log of every intermediate offline edit. This bounds queue size and minimizes transactional payloads.

10. Convergence Without Coordination

Ultimately, the power of this architecture lies in its ability to guarantee eventual consistency without distributed locks, consensus protocols, or permanent network connections.

By ensuring that local mutations are atomically recorded, pushed prior to pull updates, isolated from destructive remote overwrites, and validated by an authoritative server-side gateway, the system allows thousands of distributed client databases to converge predictably over time.

EXEC
Architectural Engagement

Need an offline-first synchronization engine?

We design and build conflict-free data relays and local SQLite container systems. Connect with our architects to blueprint your platform's offline capability.

Ledger Index
End of Specification
Document Directory