CKSyncEngine: Can Long-Offline Devices Miss CloudKit Change Notifications?

Problem Description: When a device (Device 2) stays offline for an extended period after a record is deleted from another synced device (Device 1) via CloudKit, is it possible for Device 2 to miss the deletion notification when it reconnects, even when using CKSyncEngine?

This scenario raises questions about whether CKSyncEngine can reliably sync changes if CloudKit archives or purges metadata related to deletions during the offline period.

Steps to Reproduce:

  1. At time t0:

· Device 1 and Device 2 sync successfully via CKSyncEngine (shared record RecordA).

  1. Device 2 goes offline.

  2. On Device 1:

· Delete RecordA; sync completes via CKSyncEngine.

  1. Wait for a duration potentially exceeding CloudKit’s change retention window (if such a window exists).

  2. Bring Device 2 back online.

  3. Observe synchronization:

· Expected Behavior: CKSyncEngine removes RecordA from Device 2.

· Observed Behavior: RecordA remains on Device 2.

Key Questions:

  1. Under these conditions, can Device 2 permanently miss the deletion event due to CloudKit’s internal metadata management?

  2. Is there a documented retention policy for CloudKit’s change history, and how does CKSyncEngine handle scenarios where this history is truncated?

  3. What is the recommended pattern to ensure no events are missed, regardless of offline duration?

Clarifications Needed:

· If CloudKit does discard deletion metadata after a period, is this considered a framework limitation, or should developers implement additional safeguards?

· Does CKSyncEngine log warnings or errors when it detects incomplete sync histories?

Environment:

· CKSyncEngine with SQLite · CloudKit Private Database · iOS/macOS latest versions

Thank you for clarifying how CKSyncEngine is designed to handle this edge case!

Answered by Frameworks Engineer in 827138022

In general no, CKSyncEngine and CloudKit in general handles devices being offline for an extended period of time.

Written by huluba in 775531021
Under these conditions, can Device 2 permanently miss the deletion event due to CloudKit’s internal metadata management?

Yes, the underlying push notification has a finite retention policy, see https://developer.apple.com/documentation/usernotifications.

But CKSyncEngine is aware of these limitations and will automatically perform a sync when the application launches after an extended period of time.

Is there a documented retention policy for CloudKit’s change history, and how does CKSyncEngine handle scenarios where this history is truncated?

While we do not provide a change history retention policy it is guaranteed that CKFetchDatabaseChangesOperation and CKFetchRecordZoneChangesOperation provide full change history otherwise they will return CKErrorChangeTokenExpired which indicates that the client should reset their sync history.

Please do note that there is currently no time limit enforced that would result in CKErrorChangeTokenExpired.

What is the recommended pattern to ensure no events are missed, regardless of offline duration?

As a CKSyncEngine adopter you shouldn't need to worry about this scenario.

If you are experiencing data loss please file a Feedback Report with a sysdiagnose so we can investigate further.

In general no, CKSyncEngine and CloudKit in general handles devices being offline for an extended period of time.

Written by huluba in 775531021
Under these conditions, can Device 2 permanently miss the deletion event due to CloudKit’s internal metadata management?

Yes, the underlying push notification has a finite retention policy, see https://developer.apple.com/documentation/usernotifications.

But CKSyncEngine is aware of these limitations and will automatically perform a sync when the application launches after an extended period of time.

Is there a documented retention policy for CloudKit’s change history, and how does CKSyncEngine handle scenarios where this history is truncated?

While we do not provide a change history retention policy it is guaranteed that CKFetchDatabaseChangesOperation and CKFetchRecordZoneChangesOperation provide full change history otherwise they will return CKErrorChangeTokenExpired which indicates that the client should reset their sync history.

Please do note that there is currently no time limit enforced that would result in CKErrorChangeTokenExpired.

What is the recommended pattern to ensure no events are missed, regardless of offline duration?

As a CKSyncEngine adopter you shouldn't need to worry about this scenario.

If you are experiencing data loss please file a Feedback Report with a sysdiagnose so we can investigate further.

CKSyncEngine: Can Long-Offline Devices Miss CloudKit Change Notifications?
 
 
Q