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:
- Change watermark: “What remote changes have I definitely observed?”
- Entity revision / version: “Which version of this object did I edit?”
- 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.
- stable
- 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
Related#
- OpenTelemetry Distributed Tracing Failure Modes: Async Context Propagation, Span Boundaries, High-Cardinality Attributes, and Head-vs-Tail Sampling Interactions
- Collector Incremental Ingestion: Cursor Watermarks, Idempotency Keys, and Duplicate Suppression Failure Modes
- Collector Incremental Polling Failure Modes: Conditional Requests, Dedupe, and Watermarks
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: 워터마크·툼스톤·멱등성·시계 왜곡 회피 권장은 여전히 유효함