Thanks for being a part of WWDC25!

How did we do? We’d love to know your thoughts on this year’s conference. Take the survey here

Key-value storage will not sync data past a certain size

I have an app which uses key-value storage and will not sync data past a certain size -- meaning that device "A" will send the data to the cloud but device "B" will never receive the updated data. Device "B" will receive the NSUbiquitousKeyValueStoreDidChangeExternallyNotification that the KVS changed but the data is empty.

The data in in the KVS is comprised of 4 keys, each containing a value of NSData generated by NSKeyedArchiver. The NSData is comprised of property-list data types (e.g. numbers, strings, dates, etc.)

I've verified that the KVS meets the limits of:

  • A total of 1 MB per app, with a per-key limit of 1 MB
  • A per-key value size limit of 1 MB, and a maximum of 1024 keys
  • A maximum length for key strings is 64 bytes using UTF8 encoding

Also, the app has never received an NSUbiquitousKeyValueStoreQuotaViolationChange notification.

Of the 4 keys, 3 of them contain no more than 30 KB of data each. However, one of the keys can contain as much as 160 KB of data which will not sync to another device. Strangely, if I constrain the data to 100 KB it will work, however, that is not ideal as it is a fraction of the necessary data.

I don't see any errors in the debug log either.

Any suggestions on what to try next to get this working?

Answered by DTS Engineer in 840749022

The iCloud key-value storage is intended to be used for storing preferences. While it has documented limits, my advice is that you stay far away from those limits. If you need to store hundreds, or even tens, of KiB of data, it’s time to use a different mechanism, with the most obvious replacement being CloudKit.

Notably, I give the same advice for the standard UserDefaults API. For example, see here.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Of the 4 keys, 3 of them contain no more than 30 KB of data each. However, one of the keys can contain as much as 160 KB of data which will not sync to another device. Strangely, if I constrain the data to 100 KB it will work, however, that is not ideal as it is a fraction of the necessary data.

For the purpose of clarity, the above should read:

Of the 4 keys, 3 of them contain values which are no more than 30 KB of data each. These 3 key-values will always perform a successful sync. However, the fourth key contains a value which can be as much as 160 KB of data and will not sync to another device. Strangely, if I constrain the data to 100 KB it will work, however, that is not ideal as it is a fraction of the necessary data.

The iCloud key-value storage is intended to be used for storing preferences. While it has documented limits, my advice is that you stay far away from those limits. If you need to store hundreds, or even tens, of KiB of data, it’s time to use a different mechanism, with the most obvious replacement being CloudKit.

Notably, I give the same advice for the standard UserDefaults API. For example, see here.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Key-value storage will not sync data past a certain size
 
 
Q