This is an expansion to this question by Robert. Originally he did not put "Managed Package" in the title so I feel like most of the answers missed that part.

I am building a managed package that is relying on custom metadata records creation. However upon researching and testing it appears that the only way to create custom metadata programmatically is by using Metadata.Operations.enqueueDeployment(). Which is unfortunate because that kicks off a deployment.

My first concern with the deployment is that I have a 10 second CPU time(specific to what I am doing) to have this deployment finished. If there's another deployment(s) in progress the creation of my custom metadata might be delayed for a while.

My second concern is that the deployment can scare the consumer of the managed package if they see random deployments occurring in their org.

I was wondering if there's somebody who is advocating for the use of custom metadata in managed packages. Curious if I am missing on something due to lack of experience with managed packages.

1 Answer 1


The only context where we dynamically do anything with custom metadata type instances (records) is during installation of our managed package where we want to dynamically create unprotected instances that are equivalent to some previous configuration approach in an upgrade. In this context there's clearly no worry about seeing a deployment happen (nothing "scary" here) since you're already in that context.

Since you cannot create triggers or other automation against CMT instances (e.g. to track creation or update) there's basically no special concerns over CPU time during the metadata API invocation.

For me, fundamentally, CMT instances should be viewed as a means to hold (protected or unprotected) static settings/configuration information. Dynamic management of them from your package's Apex will harm performance of the org by disrupting caching of these instances.

If you need to have more dynamic behaviour I would suggest CMTs are not the right vehicle, though I do understand that this it itself might make it more painful to transfer your "dynamic configuration" from one org to another (including in sandbox creation).

Perhaps you could store your "dynamic configuration" in custom objects and have a means to turn this into a JSON representation exported and imported through a custom LWC or similar?

  • Also, enqueueDeployment(container, callback) is asynchronous, so it'll have a 60 sec CPU timeout (not 10 as indicated in the question).
    – arut
    Commented Mar 31, 2021 at 7:32
  • @arut I have a different reason for the 10 seconds. It's linked to a Flow.
    – Arthlete
    Commented Mar 31, 2021 at 7:33
  • 1
    Something I didn't specifically mention here around performance is the use of Entity and Field Definitions; I don't know if it changed in a recent release (Salesforce has had some focus on performance improvements recently) but these were disastrously slow to query up to at least a year to 18 months back and can cause real problems if you have a lot of CMT instances to query and resolve to Schema. See this answer and others for more on this.
    – Phil W
    Commented Mar 31, 2021 at 7:47
  • @PhilW Thank you so much for sharing this. I was not aware but now I am learning quickly. The one issue I am seeing with custom objects is moving them from org to org. The user setting things up can consume a lot of their time. Now I am not sure how to move that from Dev to QA without asking them to repeat everything again. I want to keep the custom objects hidden so I can't let them export and use dataloader. The creation will be wrapped in a flow. Can I utilize SFDX to deploy to a diff org through the managed package?
    – Arthlete
    Commented Mar 31, 2021 at 7:57
  • 1
    SFDX certainly supports data export/import across orgs - we use an extended version of this (a custom SFDX plugin) to handle more complex data trees that the OOTB command can support, but as long as you have a relatively straight forward object record tree you should be able to use that. The alternative is some custom export/import mechanism, perhaps as an LWC using JSON as the representation as I mentioned, that the QA or DevOps folks can use. It comes down to whether QA/DevOps are comfortable using a command line or not.
    – Phil W
    Commented Mar 31, 2021 at 10:04

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .