iCloud does throttle data syncing after all

Have you ever noticed that sometimes, despite having a good Internet connection, iCloud just won’t synchronise properly, leaving your Mac and devices with different information? Apple has just explained why this can happen even when iCloud is working fine, and your Mac and devices appear well connected to it. This may be the result of iCloud throttling the sync that should be occurring, and there’s little or nothing you can do about it.

iCloud consists of two main services: iCloud Drive to sync files stored locally and in its cloud storage, and data syncing for apps that share databases in iCloud and use CloudKit to manage their shared data. Those who are paying Apple princely sums each month to store files in terabytes of iCloud Drive will be relieved to know that this throttling doesn’t appear to involve iCloud Drive at all, although that does of course have a storage quota enforced. Throttling only affects shared data that relies on CloudKit.

I came to suspect that iCloud imposed quotas on its use nearly six years ago, when I was exploring the only command tool that provides any useful information about iCloud, brctl. When examining one of its dumps, I came across an entry for syncUpBudget referring to BRCSyncBudgetThrottle, and another item global sync up budget giving the budget available. As with almost everything in brctl and iCloud generally, there appeared to be no documentation of these.

I concluded:
“BRCSyncBudgetThrottle and sync budgets provide more general insights into how iCloud operates, and implies that heavy users with limited budgets (presumably those using only the 5 GB free iCloud storage) may find its performance ‘throttled’ at times. This is a topic which Apple doesn’t appear to have detailed anywhere, but clearly of great interest if you are suffering performance problems.”

A few days ago, Apple published a Technote (TN3162) for developers ,titled Understanding CloudKit throttles, where it reveals that “CloudKit can enforce throttles when it deems necessary on any app or service that uses the CloudKit framework, CloudKit Web Services, CloudKit JS, NSPersistentCloudKitContainer, and NSUbiquitousKeyValueStore.”

Although this Technote is remarkably coy about providing any substantive details of these throttles, its purpose is to explain to developers of software using any of those CloudKit-based services how to handle the error messages their software will encounter when a throttle is applied. No detail is given as to the quotas or limits that determine when throttles might be applied.

The Technote details two situations that may result in iCloud’s CloudKit server throttling a request:

  • when local software issues too many CloudKit requests in too short a period, when they may exceed the rate limit, which isn’t further specified;
  • when local software uses CloudKit “in an inappropriate pattern”, such as triggering recurring spikes in requests across several client devices at the same time.

Devices can also apply their own local system throttles in some circumstances; for example, when the device’s battery runs low, its system may well throttle CloudKit requests until the device has been recharged to a specific battery level. Those shouldn’t affect the syncing of other devices, though.

When local software makes a request of CloudKit that is throttled, this is most commonly reflected as the service being unavailable, although fuller information is available to the software in addition to an HTTP status code of 503. That should usually give a retry interval (the retry-after time) in seconds. Until that retry interval has expired, all further requests will be refused, and after that CloudKit could still decide to re-apply the throttle.

It’s clear that apps and other software that could issue multiple requests of CloudKit over a short period, or could trigger a pattern of requests that iCloud doesn’t like, could be responsible for situations in which syncing of shared data with iCloud is put on hold. Unless the client app responds appropriately to that throttling, you could be advised incorrectly that iCloud isn’t available, or worse still the sync could simply fail silently.

Perhaps the worst approach the user could then try is one of the solutions most commonly recommended: turning iCloud off and back on again, as it has no effect on the retry interval, and could trigger further throttling. If you suspect that throttling has occurred, your only sources of information are the copious and baffling dumps provided by brctl, or CloudKit entries in the log, as provided by my utilities Cirrus and Mints.

As you’d expect, efforts to discover any explanation in Apple’s user support documentation have proved unsuccessful, although there’s no shortage of advice to increase your iCloud storage quota, as if that could solve every iCloud problem.