Custom Metadata Types are deployable metadata records — "environment-specific config," "mapping tables," "business rules" that move between sandboxes and production via Change Sets / DX. Modern replacement for Custom Settings: data IS metadata, so it deploys with the rest of your code. Admin-friendly to author; developer-friendly to read at runtime.
- Open Setup → Custom Metadata Types
Setup gear → Quick Find: Custom Metadata Types → Custom Metadata Types.
- Click New Custom Metadata Type
Top-right.
- Set Label, Plural Label, Object Name
Label is the display name. Plural Label is for the records collection. Object Name auto-derives with __mdt suffix.
- Set Visibility (Public / Protected)
Public: subscribers can read records. Protected: only the package owner. For internal types, Public is fine.
- Save → add Custom Fields to the type
Each Custom Metadata Type needs fields to store config values. Same field types as Custom Objects, plus Picklist, Checkbox, Number, Text.
- Add records via the Manage button
On the type's detail page → Manage → New. Each record is a deployable metadata row.
- Read at runtime via SOQL or @AuraEnabled metadata access
Apex: SOQL queries on the __mdt object. LWC: @wire to wire-adapter for metadata. Reads are cached and don't count against query governor limits.
Required.
Required. __mdt suffix.
Required.
- Custom Metadata Types replaced Custom Settings for new development. Modern best practice: use Custom Metadata for deployable config; use Custom Settings only for org-only config that shouldn't deploy.
- Records are metadata — every change to a record is a metadata change. Bulk record updates via UI are fine; via API in production is restricted (need Modify Metadata permission).
- SOQL queries on __mdt are FREE (don't count against governor limits) and CACHED. This is a key perf advantage — accessing config via Custom Metadata is fast.