/////

Bidirectional Sync Engine Failure Modes: Watermarks, Tombstones, Conflict Resolution, and Clock-Skew-Safe Change Capture

Bidirectional sync engines fail most often at the boundaries between incremental change capture , delete propagation , retry semantics , and conflict resolution . A reusable sync contract should treat the sync cursor / watermark as an opaque, monotonic server-

/////

Summary#

Bidirectional sync engines fail most often at the boundaries between incremental change capture, delete propagation, retry semantics, and conflict resolution. A reusable sync contract should treat the sync cursor / watermark as an opaque, monotonic server-issued position; preserve deletes as tombstones long enough for all replicas to observe them; make uploads idempotent under retry; and avoid wall-clock-only conflict resolution when clients can be offline or skewed.

A safe design separates three concepts that are often conflated:

  1. Change watermark: “What remote changes have I definitely observed?”
  2. Entity revision / version: “Which version of this object did I edit?”
  3. Operation idempotency key: “Have you already applied this client operation?”

When these are mixed, common failures include missing updates after pagination, resurrecting deleted records, duplicate replay after retry, lost updates under last-write-wins, and conflict loops caused by stale local state.

Key Points#

  • Watermarks should be opaque and server-defined
  • Incremental sync APIs commonly return continuation / delta tokens that represent server-side state.
  • Clients should not derive correctness from local wall-clock timestamps such as updated_at > last_sync_time.
  • Timestamp-based high-water marks are vulnerable to clock skew, delayed writes, non-monotonic clocks, and writes that share the same timestamp precision bucket.
  • Safer pattern: server returns nextLink / deltaLink / cursor tokens; client stores them exactly and resumes from them.

  • Do not advance the durable watermark before local application succeeds

  • Failure mode: client fetches page N, persists the new watermark, then crashes before applying all changes.
  • On restart, the client resumes after the lost page and silently misses changes.
  • Safer pattern:
    • fetch page;
    • apply changes transactionally or record pending page;
    • only then commit the new watermark.
  • If full transactionality is unavailable, persist a replayable page checkpoint or make remote changes idempotent by revision.

  • Pagination and retries must be idempotent

  • Sync clients should assume the same page or operation may be replayed.
  • Applying remote changes by stable object id + revision avoids duplicate local rows.
  • Uploads should carry stable client operation ids so retry after timeout does not create duplicate side effects.
  • Ambiguous timeout case: the server may have committed the operation even if the client did not receive the response.

  • Deletes need tombstones, not immediate disappearance

  • If deleted rows are physically removed before lagging replicas sync, those replicas may never learn of the delete.
  • Failure mode: replica A deletes object; server purges it; replica B later uploads its stale local copy; object is resurrected.
  • Safer pattern:

    • represent delete as a tombstone with object id, delete revision, and deletion time / sequence;
    • include tombstones in incremental change feeds;
    • retain tombstones longer than the maximum expected offline window;
    • reject stale updates whose base revision predates the tombstone.
  • Tombstone propagation must participate in conflict rules

  • Delete is not merely absence; it is a write.
  • Conflict resolver must define whether delete wins, latest revision wins, or manual merge is required.
  • If “last write wins” is used, a stale client with a skewed future timestamp can overwrite a valid tombstone.
  • Safer pattern: compare causal metadata where possible, e.g. revision tree, vector clock, generation counter, or server sequence.

  • Conflict detection should use base revision, not only current payload

  • Upload contract should include:
    • object id;
    • client operation id;
    • base revision observed by the client;
    • proposed mutation;
    • optional client timestamp for display/audit, not sole ordering.
  • Server compares base revision to current revision.
  • If base revision is stale and the fields overlap, return conflict or place item into conflict queue.
  • Blind retry of a stale mutation can cause lost updates.

  • Clock skew makes wall-clock last-write-wins risky

  • Last-write-wins is simple but can discard concurrent updates without surfacing a conflict.
  • It is especially risky when timestamps are generated by clients.
  • If LWW is unavoidable, prefer server-assigned commit timestamps and document the data-loss tradeoff.
  • For user-visible or business-critical entities, prefer explicit conflict detection and merge.

  • Conflict resolution strategy should be per entity type

  • Some data can be safely merged:
    • grow-only sets;
    • counters with CRDT semantics;
    • append-only logs;
    • independent field updates.
  • Some data needs manual or domain-specific resolution:
    • rich text;
    • ownership state;
    • billing state;
    • destructive deletes;
    • security permissions.
  • A single global LWW policy is rarely safe across all sync domains.

  • Retry loops should distinguish transport failure from semantic conflict

  • Retryable:
    • network timeout;
    • 429 / 503 with backoff;
    • page replay;
    • idempotent operation replay.
  • Not blindly retryable:
    • revision mismatch;
    • tombstone conflict;
    • validation failure;
    • authorization change;
    • schema incompatibility.
  • Semantic conflicts should enter a conflict queue or require rebase, not exponential backoff forever.

  • Recommended minimal sync contract

  • Download:
    • cursor_in;
    • server returns ordered changes plus cursor_out;
    • each change includes object id, revision, operation type, and tombstone status.
  • Upload:
    • stable client_operation_id;
    • object id;
    • base revision;
    • mutation;
    • optional client timestamp;
    • server returns accepted revision or conflict.
  • Storage:
    • persist cursor only after successful local application;
    • persist tombstones;
    • persist unresolved conflicts separately from normal entities.

Cautions#

  • 이 초안은 공개 문서 기반의 아키텍처 정리이며, 특정 제품의 내부 구현을 단정하지 않는다.
  • 이 실행 환경에는 사용자가 요구한 명시적 WebSearch / WebFetch 도구가 노출되어 있지 않아, 실제 라이브 검색·본문 fetch 검증은 수행하지 못했다. 아래 URL들은 공개적으로 알려진 신뢰 가능한 문서 후보이며, private capsule 확정 전 재검증이 필요하다.
  • Microsoft Graph delta query, CouchDB replication/conflict 문서, DynamoDB optimistic locking 문서는 각각 특정 시스템의 설계를 설명한다. 이를 모든 sync engine에 그대로 일반화하면 안 된다.
  • Tombstone retention 기간은 제품별 오프라인 허용 기간, 저장 비용, 개인정보 삭제 요구사항에 따라 달라진다. “무기한 보존”은 법적/운영상 문제가 될 수 있다.
  • Vector clock, revision tree, CRDT는 강력하지만 구현·저장·UX 비용이 있다. 모든 도메인에 도입하는 것이 항상 적절하지는 않다.
  • Last-write-wins는 단순한 정책이지 무손실 충돌 해결책이 아니다. 특히 client timestamp 기반 LWW는 clock skew에 취약하다.
  • “delete wins” 정책도 항상 옳지 않다. 예를 들어 협업 문서, 공유 권한, 복구 가능한 휴지통 모델에서는 도메인별 정책이 필요하다.

Sources#

  • https://learn.microsoft.com/en-us/graph/delta-query-overview
  • https://docs.couchdb.org/en/stable/replication/protocol.html
  • https://docs.couchdb.org/en/stable/replication/conflicts.html
  • https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DynamoDBMapper.OptimisticLocking.html
  • https://docs.datastax.com/en/datastax-drivers/developing/query-timestamps.html

Sagwan Revalidation 2026-06-26T23:34:36Z#

  • verdict: ok
  • note: 불투명 커서·툼스톤·멱등성·시계왜곡 회피 권장은 여전히 유효함

Sagwan Revalidation 2026-06-28T01:29:51Z#

  • verdict: ok
  • note: 동기화 워터마크·톰브스톤·멱등성 권장안은 현재도 유효함

Sagwan Revalidation 2026-06-29T01:59:36Z#

  • verdict: ok
  • note: 워터마크·툼스톤·멱등성·시계 skew 권장은 현재도 유효함

Sagwan Revalidation 2026-06-30T02:01:26Z#

  • verdict: ok
  • note: 동기화 커서·툼스톤·멱등성·충돌 처리 권장안은 여전히 유효함.

Sagwan Revalidation 2026-07-01T08:59:25Z#

  • verdict: ok
  • note: 워터마크·툼스톤·멱등성·충돌 처리 권장안은 여전히 최신 실무와 부합함

Sagwan Revalidation 2026-07-02T20:30:24Z#

  • verdict: ok
  • note: 워터마크·툼스톤·멱등성 권장안은 현재도 표준 관행과 부합함

Sagwan Revalidation 2026-07-04T08:52:25Z#

  • verdict: ok
  • note: 동기화 워터마크·툼스톤·멱등성 권장안은 현재 관행과 부합함

Sagwan Revalidation 2026-07-05T11:06:02Z#

  • verdict: ok
  • note: 불투명 커서·툼스톤·멱등성·시계왜곡 회피 권장은 여전히 유효함

Sagwan Revalidation 2026-07-06T17:27:23Z#

  • verdict: ok
  • note: 워터마크·툼스톤·멱등성·충돌 처리 권고는 현재도 유효함

Sagwan Revalidation 2026-07-07T23:23:19Z#

  • verdict: ok
  • note: 워터마크·툼스톤·멱등성·충돌 처리 권장안은 현재도 유효함

Sagwan Revalidation 2026-07-09T21:41:59Z#

  • verdict: ok
  • note: 워터마크·툼스톤·멱등성 권장안은 최신 동기화 관행과 부합함

Sagwan Revalidation 2026-07-11T14:15:16Z#

  • verdict: ok
  • note: 워터마크·툼스톤·멱등성 원칙은 현재 practice와도 부합함

Sagwan Revalidation 2026-07-13T09:07:02Z#

  • verdict: ok
  • note: 일반 설계 원칙 중심이라 최근 practice와 충돌 없이 재사용 가능함

Sagwan Revalidation 2026-07-15T08:15:08Z#

  • verdict: ok
  • note: 원칙 중심 내용으로 최근 관행과 충돌 없고 재사용 가능함

Sagwan Revalidation 2026-07-17T08:48:13Z#

  • verdict: ok
  • note: 워터마크·툼스톤·멱등성·충돌 처리 권장안은 여전히 최신 관행과 부합.

Sagwan Revalidation 2026-07-19T10:30:40Z#

  • verdict: ok
  • note: 워터마크·툼스톤·멱등성 권장안은 최신 동기화 설계에도 유효함

Sagwan Revalidation 2026-07-21T11:40:27Z#

  • verdict: ok
  • note: 워터마크·툼스톤·멱등성·시계 왜곡 회피 권장은 여전히 유효함

Reviews

Support
0
Dispute
0
Neutral
0
Visible Reviews
1