Salesforce Dictionary - Free Salesforce GlossarySalesforce Dictionary
Full Custom Metadata Type entry
How-to guide

How to create a Custom Metadata Type

Creating a Custom Metadata Type is similar to creating a custom object. The difference shows up at deployment time, where records travel with metadata changes instead of requiring separate data loads. Plan the field types, decide between Public and Protected visibility, and design the records as a deployable artifact from the start.

By Dipojjal Chakrabarti · Founder & Editor, Salesforce DictionaryLast updated May 16, 2026

Creating a Custom Metadata Type is similar to creating a custom object. The difference shows up at deployment time, where records travel with metadata changes instead of requiring separate data loads. Plan the field types, decide between Public and Protected visibility, and design the records as a deployable artifact from the start.

  1. Confirm Custom Metadata is the right tool

    Use Custom Metadata for static configuration that should deploy with code, support cross-object relationships, and stay out of the data tier. Use Hierarchy Custom Settings if User or Profile inheritance is required. Use List Custom Settings only when production admin editing without deploy is critical.

  2. Create the Custom Metadata Type

    Setup > Custom Metadata Types > New Custom Metadata Type. Enter label, plural label, and API name. The API name automatically gets the __mdt suffix. Choose Public or Protected visibility based on whether external code should access the records.

  3. Add custom fields

    From the type detail page > Custom Fields & Relationships > New. Pick the field type. Metadata Relationship fields let one record reference another Custom Metadata record or an EntityDefinition/FieldDefinition. Picklist fields are supported, unlike on Custom Settings.

  4. Build records via the Manage button

    Setup > Custom Metadata Types > the type > Manage Records > New. For each record, enter the Label, Developer Name (the primary key for getInstance lookups), and the field values. Records appear in the manifest as separate metadata files.

  5. Reference from Apex with getInstance or SOQL

    Tax_Rate__mdt rate = Tax_Rate__mdt.getInstance(''US''); for direct lookup. List<Tax_Rate__mdt> rates = [SELECT Country__c, Rate__c FROM Tax_Rate__mdt]; for bulk read. Both access patterns are free against SOQL governor limits.

  6. Reference from formulas via the CustomMetadata global

    Formula syntax: CustomMetadata.Tax_Rate__mdt.Default.Rate__c (prefixed with the formula-engine dollar global) in formula fields. This is the formula-engine path to Custom Metadata, useful for business rules that depend on configurable thresholds without touching Apex.

  7. Deploy via change set or metadata API

    Include the Custom Metadata Type definition AND the individual records in the change set or package manifest. Each record is its own metadata file (Tax_Rate.US.md-meta.xml). The deployment moves both type and records to the target org.

  8. Version the metadata in source control

    Custom Metadata records belong in the version-controlled repo alongside Apex classes. Use SFDX project format. Pull request reviews catch configuration changes the same way they catch code changes, which is the major workflow win over Custom Settings.

Visibility (Public or Protected)remember

Public for org-wide access. Protected for managed-package-only access. Drives whether subscriber-org code can read the records.

Field Typesremember

Text, Number, Date, Checkbox, Picklist, Long Text Area, Metadata Relationship. Broader than Custom Settings; picklists and relationships work natively.

Record Developer Nameremember

The primary key used by getInstance and formula lookups. Cannot be changed after creation without breaking references.

Gotchas
  • Custom Metadata records are metadata. Inserts and updates via API require Metadata API or the Metadata.Operations Apex class, not standard DML. Apex DML on __mdt objects throws an error.
  • Custom Metadata does not support User or Profile hierarchy. Use Hierarchy Custom Settings if different users need different values for the same setting.
  • Flow Get Records on Custom Metadata counts against SOQL governor limits because Flow does not use the Apex cache. Cache results in Flow variables when reading multiple times.
  • Protected visibility is irrevocable once a managed package is uploaded. Downgrading from Protected to Public breaks the package security boundary, so design carefully up front.
  • Deploying Custom Metadata records requires explicit inclusion in the change set or package manifest. Forgetting to include records during deployment is a common cause of post-deployment behavior changes.

See the full Custom Metadata Type entry

Custom Metadata Type includes the definition, worked example, deep dive, related terms, and a quiz.