Production container at the record type limit — 98 of 250 slots are dead CD_ types from NSPersistentCloudKitContainer

Our production container has hit the record type ceiling. Any schema change that adds a new type is rejected with:

The request was not allowed: max user record types limit exceeded

A schema export taken from production with cktool shows exactly 250 record types:

148   our active schema, CKSyncEngine based
 98   CD_* types, auto-generated by NSPersistentCloudKitContainer years ago, before we
      migrated to CKSyncEngine. The current binary does not use that mirroring path at all
      (every ModelConfiguration is created with .cloudKitDatabase: .none, and there is not a
      single CD_ literal in our source). They are never read and never written.
  4   system and pre-migration legacy types

So 39% of the budget belongs to a framework we no longer use, and because the production schema is append-only we cannot reclaim any of it. Our effective ceiling is 152 types, and we have used 148.

The user-visible symptom is CKError 12, "Cannot create new type <Name> in production schema". The record is created locally, the client uploads it, the server correctly rejects it, and the data never reaches the user's other Mac or iPad. It fails silently from the user's point of view. Eight shipped features are affected. One of them carries allergen availability, which our restaurant customers print on recipes and communicate to guests, so this is not cosmetic for us.

The wall is exactly 250 and it is deterministic: a batch of 13 new types was rejected (245 + 13), and a batch of 5 succeeded, landing the container on 250 precisely.

What I have already done:

  • Filed FB24239614 with the full schema export attached.
  • Opened Developer Support case 20000130013570, which came back with general information about what CloudKit is and did not address the quota.
  • Adopted an internal rule that new synchronised data lives as a field or blob on an existing record type wherever the data model allows. Adding fields to existing types works fine and does not consume the budget — that part is not the problem. Some of the eight genuinely need to be their own type.

My questions:

  1. Is there any supported way to reclaim record type slots left behind by NSPersistentCloudKitContainer after migrating off it? Everything I have found says the production schema is append-only with no exceptions, but these types were generated by the framework rather than authored by us, so I wanted to ask before assuming.

  2. If slots cannot be reclaimed, is a per-container record type limit increase something that can be requested through a channel that reaches the CloudKit team? The Developer Support case did not get there.

  3. Has anyone migrated a container that uses CKShare-based sharing to a new container? Our model gives each customer a shared zone that their staff accept through a CKShare. My understanding is that shares cannot be migrated, which would force every one of those users to re-accept access. I would like to know if that understanding is correct before treating it as an option.

Happy to share the container identifier with an Apple engineer, and the Feedback report has the full export.

The answer to your questions is no:

  • There is no supported way to reclaim record type slots in a CloudKit production environment, because a CloudKit production schema is additive only.
  • There is currently no formal channel to request a per-container record type limit increase.
  • Participating a share requires user interaction, and so I believe you are right – migrating a share to a new CloudKit container will need the participants re-accept the invitations.

Your feedback report (FB24239614) is now on the CloudKit team. You might want to allow more time to see if the team can respond your request.

I'd say that the best option in this situation is still that you manage to migrate to a new CloudKit container (before the problem grows bigger). That will clean up the record types you don't need any more, and allow space for future evolvement.

Adding a new container to contain the new record types and associating the data in your app is probably doable, but that makes your data model fragile, and over time, your code will become harder to maintain.

Best,
——
Ziqiao Chen
 Worldwide Developer Relations.

Production container at the record type limit — 98 of 250 slots are dead CD_ types from NSPersistentCloudKitContainer
 
 
Q