All storiesIntegration

Out-of-order document saves: stop older results overwriting newer versions

Use explicit version ordering and guarded publication to handle duplicates and delayed save delivery without moving content backward.

Out-of-order document saves: stop older results overwriting newer versions: Source revision, Candidate object, Duplicate guard, Publish guard.
Integration / Office SDK

Store each save result as a candidate, then advance the current version only when its source revision is allowed to do so. Arrival time and worker completion time are not reliable ordering rules. A slow save for revision A must not replace revision B merely because A finished downloading later.

Establish a trustworthy revision order

Inspect the selected integration's version and event semantics. A monotonic source revision can support ordering if the provider documents that guarantee within the relevant document or session scope. An opaque revision identifier may support equality checks without supporting numeric comparison. Timestamps from different machines are weaker evidence because clocks and precision differ. If the provider supplies no ordering guarantee, serialize the relevant workflow or use a documented retrieval of authoritative current state. Do not invent ordering by sorting arbitrary IDs or comparing arrival times.

Candidate objects and guarded publication

Persist each candidate under a version specific key instead of overwriting a shared current file path immediately. After validation, update the current version pointer only if the expected predecessor or accepted source revision still matches. This guarded publication prevents a slow worker from undoing a faster newer save. Retain enough metadata to explain why a candidate was rejected as stale. Depending on retention policy, that object can become a historical version or be cleaned up after a reconciliation period rather than remaining an unexplained orphan.

candidate: source revision B → immutable object B
publish: advance current only if the expected state still matches
late candidate: source revision A → retain or discard by policy

The publication guard belongs at the atomic state change. Checking the current version before a large download leaves a race: another worker can publish while that download is in progress. Recheck with a compare-and-update transaction, conditional object operation, or the equivalent supported by your storage design.

Distinguish a source revision from a delivery ID. Two deliveries can describe one revision, while two distinct revisions can arrive in reverse order. Deduplicating delivery IDs does not solve revision ordering. If revision identifiers are opaque, compare them only in ways the provider documents; lexical sorting of strings is not evidence of chronology.

A reconciliation process must use the same guard as the normal worker. Otherwise an operator's repair can reintroduce the exact race the production path prevents. Its report should identify the candidate revision, prior current version, publication decision, and retained object. This makes a stale rejection explainable without requiring operators to inspect document bytes.

A delayed candidate is checked after a newer revision has already been published.
Figure 1. The guard must run when publishing, not only before retrieval begins.

Duplicates and interrupted workers are separate cases

Two deliveries of the same logical save should converge on one business effect. Keep a stable operation identity and track whether retrieval, validation, and publication completed. A duplicate that arrives while processing is pending should not launch uncontrolled parallel downloads. A retry after a worker crash must still be able to resume incomplete work. Deduplication and version ordering solve different problems: one avoids repeating the same action, while the other prevents an older distinct action from replacing newer content that has already been published.

Reverse A and B in a controlled test

Create revision A, then revision B of a test spreadsheet. Delay retrieval or publication of A until B has become the current business version. Release A and inspect the pointer, download result, history, and audit records. The current document should remain B, while A follows the documented historical or cleanup policy. Repeat with two deliveries of B and with a crash immediately after its object is stored. These controlled failures show whether ordering protects the complete storage path, not just the callback handler.

Three save conditions call for different recovery decisions.
Figure 2. A healthy callback count does not establish that the latest durable file is correct.

Watch whether the business version converges

  • Track stale candidates, duplicate operations, and incomplete publications separately.
  • Alert when the business version remains behind the authoritative editing state beyond the agreed interval.
  • Retain source revision and business version mappings for diagnosis.
  • Provide a reconciliation job with the same publication guards as normal processing.
  • Confirm that cleanup cannot delete the object referenced by the current pointer.

Further reading

Back to all stories

Keep reading.

All stories